From 37984ea7044aefa49d6fcb76a8028557339a3bd8 Mon Sep 17 00:00:00 2001 From: Wujing Yao Date: Mon, 23 Dec 2019 16:16:17 -0800 Subject: [PATCH] Remove SAR example applications --- .../alexa-skill-kit-sdk-factskill/index.js | 146 - .../package.json | 8 - .../template.yaml | 19 - .../alexa-skill-kit-sdk-howtoskill/index.js | 137 - .../package.json | 8 - .../alexa-skill-kit-sdk-howtoskill/recipes.js | 1536 ----- .../template.yaml | 19 - .../alexa-skill-kit-sdk-triviaskill/index.js | 371 -- .../package.json | 8 - .../question.js | 755 --- .../template.yaml | 19 - .../index.js | 371 -- .../lambda_function.py | 207 - .../package.json | 8 - .../question.js | 755 --- .../template.yaml | 22 - .../alexa-skills-kit-color-expert/index.js | 225 - .../package.json | 8 - .../alexa-skills-kit-color-expert/question.js | 755 --- .../template.yaml | 22 - .../testEvent.json | 47 - .../alexa-smart-home-skill-adapter/index.js | 409 -- .../package.json | 8 - .../alexa-smart-home-skill-adapter/recipes.js | 1536 ----- .../template.yaml | 19 - examples/apps/algorithmia/index.js | 120 - examples/apps/algorithmia/package.json | 8 - examples/apps/algorithmia/template.yaml | 29 - .../api-gateway-authorizer-nodejs/index.js | 379 -- .../package.json | 8 - .../template.yaml | 19 - .../lambda_function.py | 223 - .../template.yaml | 19 - .../README.md | 45 - .../cors-config.json | 7 - .../cors-util.js | 81 - .../cors-util.test.js | 84 - .../package-lock.json | 5075 ----------------- .../package.json | 21 - .../routes/root.js | 19 - .../routes/test.js | 24 - .../template.yaml | 50 - examples/apps/cfn-look-up-ami-ids/index.js | 106 - .../apps/cfn-look-up-ami-ids/package.json | 8 - .../apps/cfn-look-up-ami-ids/template.yaml | 15 - examples/apps/cfn-stack-outputs/index.js | 88 - examples/apps/cfn-stack-outputs/package.json | 8 - examples/apps/cfn-stack-outputs/template.yaml | 19 - examples/apps/cloudfront-ab-test/index.js | 61 - .../apps/cloudfront-ab-test/template.yaml | 19 - .../apps/cloudfront-ab-test/testEvent.json | 36 - .../index.js | 18 - .../template.yaml | 21 - .../testEvent.json | 42 - .../apps/cloudfront-http-redirect/index.js | 15 - .../cloudfront-http-redirect/template.yaml | 19 - .../cloudfront-modify-querystring/index.js | 27 - .../template.yaml | 21 - .../testEvent.json | 37 - .../index.js | 20 - .../template.yaml | 20 - .../testEvent.json | 35 - .../index.js | 85 - .../template.yaml | 21 - .../testEvent.json | 30 - .../index.js | 40 - .../template.yaml | 21 - .../testEvent.json | 30 - .../index.js | 44 - .../package.json | 8 - .../template.yaml | 21 - .../testEvent.json | 24 - .../cloudfront-response-generation/index.js | 24 - .../template.yaml | 21 - .../cloudfront-simple-remote-call/index.js | 50 - .../template.yaml | 22 - .../testEvent.json | 36 - .../cloudwatch-alarm-to-slack-python/index.js | 120 - .../lambda_function.py | 91 - .../package.json | 8 - .../template.yaml | 37 - .../index.js | 120 - .../lambda_function.py | 91 - .../package.json | 8 - .../template.yaml | 37 - .../apps/cloudwatch-alarm-to-slack/index.js | 134 - .../cloudwatch-alarm-to-slack/package.json | 8 - .../cloudwatch-alarm-to-slack/template.yaml | 37 - .../cloudwatch-logs-process-data/index.js | 15 - .../cloudwatch-logs-process-data/package.json | 8 - .../template.yaml | 23 - .../apps/cloudwatch-logs-to-loggly/index.js | 130 - .../cloudwatch-logs-to-loggly/package.json | 8 - .../cloudwatch-logs-to-loggly/template.yaml | 24 - examples/apps/cognito-sync-trigger/index.js | 32 - .../apps/cognito-sync-trigger/package.json | 8 - .../apps/cognito-sync-trigger/template.yaml | 23 - .../config-rule-change-triggered/index.js | 132 - .../template.yaml | 19 - examples/apps/config-rule-periodic/index.js | 77 - .../apps/config-rule-periodic/template.yaml | 19 - .../lambda_function.py | 156 - .../datadog-process-rds-metrics/template.yaml | 22 - .../lambda_function.py | 14 - .../template.yaml | 39 - .../dynamodb-process-stream-python3/index.js | 65 - .../lambda_function.py | 13 - .../lib/mysplunklogger.js | 92 - .../template.yaml | 38 - .../apps/dynamodb-process-stream/index.js | 13 - .../dynamodb-process-stream/template.yaml | 39 - .../aws-greengrass-core-sdk/index.js | 7 - .../aws-greengrass-core-sdk/iotdata.js | 148 - .../aws-greengrass-core-sdk/lambda.js | 116 - .../aws-greengrass-core-sdk/secretsmanager.js | 95 - .../aws-greengrass-core-sdk/util.js | 41 - .../greengrass-hello-world-nodejs/index.js | 42 - .../license/license.txt | 201 - .../template.yaml | 23 - .../greengrassHelloWorld.py | 56 - .../greengrasssdk/IoTDataPlane.py | 154 - .../greengrasssdk/Lambda.py | 139 - .../greengrasssdk/SecretsManager.py | 160 - .../greengrasssdk/__init__.py | 9 - .../greengrasssdk/client.py | 16 - .../greengrasssdk/utils/__init__.py | 0 .../greengrasssdk/utils/testing.py | 35 - .../license/license.txt | 201 - .../apps/greengrass-hello-world/template.yaml | 21 - .../hello-world-python/lambda_function.py | 14 - examples/apps/hello-world-python/license.txt | 201 - examples/apps/hello-world-python/readme | 0 .../apps/hello-world-python/template.yaml | 19 - .../hello-world-python3/lambda_function.py | 12 - examples/apps/hello-world-python3/license.txt | 201 - examples/apps/hello-world-python3/readme | 0 .../apps/hello-world-python3/template.yaml | 19 - examples/apps/hello-world/index.js | 12 - examples/apps/hello-world/license.txt | 201 - examples/apps/hello-world/readme | 0 examples/apps/hello-world/template.yaml | 19 - examples/apps/hello-world/testEvent.json | 5 - examples/apps/https-request/index.js | 31 - examples/apps/https-request/license.txt | 201 - examples/apps/https-request/readme | 0 examples/apps/https-request/template.yaml | 19 - .../apps/image-processing-service/index.js | 141 - .../apps/image-processing-service/license.txt | 201 - examples/apps/image-processing-service/readme | 0 .../image-processing-service/template.yaml | 21 - .../lambda_function.py | 61 - .../license.txt | 201 - .../inbound-ses-spam-filter-python/readme | 0 .../requirements.txt | 1 - .../template.yaml | 24 - .../apps/inbound-ses-spam-filter/index.js | 54 - .../apps/inbound-ses-spam-filter/license.txt | 201 - examples/apps/inbound-ses-spam-filter/readme | 0 .../inbound-ses-spam-filter/template.yaml | 28 - .../apps/inspector-scheduled-run/index.js | 40 - .../apps/inspector-scheduled-run/license.txt | 201 - examples/apps/inspector-scheduled-run/readme | 0 .../inspector-scheduled-run/template.yaml | 22 - .../index.js | 35 - .../license.txt | 201 - .../readme | 0 .../template.yaml | 29 - .../testEvent.json | 11 - .../aws_kinesis_agg/__init__.py | 25 - .../aws_kinesis_agg/deaggregator.py | 72 - .../aws_kinesis_agg/kpl_pb2.py | 202 - .../lambda_function.py | 35 - .../requirements.txt | 1 - .../template.yaml | 30 - .../lambda_function.py | 24 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 29 - .../kinesis-analytics-process-record/index.js | 13 - .../license.txt | 201 - .../kinesis-analytics-process-record/readme | 38 - .../template.yaml | 29 - .../testEvent.json | 11 - .../lambda_function.py | 40 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 27 - .../index.js | 37 - .../license.txt | 201 - .../kinesis-firehose-apachelog-to-csv/readme | 38 - .../template.yaml | 27 - .../testEvent.json | 11 - .../lambda_function.py | 90 - .../license.txt | 201 - .../requirements.txt | 1 - .../template.yaml | 27 - .../index.js | 78 - .../license.txt | 201 - .../template.yaml | 27 - .../testEvent.json | 11 - .../index.js | 90 - .../lib/mysplunklogger.js | 94 - .../template.yaml | 21 - .../testEvent.json | 27 - .../lambda_function.py | 26 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 29 - .../lambda_function.py | 34 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 25 - .../index.js | 22 - .../license.txt | 201 - .../readme | 38 - .../template.yaml | 25 - .../testEvent.json | 19 - .../kinesis-firehose-process-record/index.js | 14 - .../license.txt | 201 - .../kinesis-firehose-process-record/readme | 38 - .../template.yaml | 27 - .../lambda_function.py | 48 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 25 - .../kinesis-firehose-syslog-to-csv/index.js | 42 - .../license.txt | 201 - .../kinesis-firehose-syslog-to-csv/readme | 38 - .../template.yaml | 25 - .../testEvent.json | 16 - .../lambda_function.py | 51 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 26 - .../kinesis-firehose-syslog-to-json/index.js | 49 - .../license.txt | 201 - .../kinesis-firehose-syslog-to-json/readme | 38 - .../template.yaml | 25 - .../lambda_function.py | 15 - .../kinesis-process-record-python/license.txt | 201 - .../apps/kinesis-process-record-python/readme | 38 - .../requirements.txt | 1 - .../template.yaml | 37 - examples/apps/kinesis-process-record/index.js | 13 - .../apps/kinesis-process-record/license.txt | 201 - examples/apps/kinesis-process-record/readme | 38 - .../apps/kinesis-process-record/template.yaml | 37 - .../lambda-canary-python3/lambda_function.py | 32 - .../apps/lambda-canary-python3/license.txt | 201 - examples/apps/lambda-canary-python3/readme | 38 - .../lambda-canary-python3/requirements.txt | 1 - .../apps/lambda-canary-python3/template.yaml | 24 - .../apps/lambda-canary/lambda_function.py | 33 - examples/apps/lambda-canary/license.txt | 201 - examples/apps/lambda-canary/readme | 38 - examples/apps/lambda-canary/requirements.txt | 1 - examples/apps/lambda-canary/template.yaml | 28 - examples/apps/lambda-test-harness/index.js | 99 - examples/apps/lambda-test-harness/license.txt | 201 - examples/apps/lambda-test-harness/readme | 38 - .../apps/lambda-test-harness/template.yaml | 25 - .../lex-book-trip-python/lambda_function.py | 519 -- .../apps/lex-book-trip-python/license.txt | 201 - examples/apps/lex-book-trip-python/readme | 38 - .../lex-book-trip-python/requirements.txt | 1 - .../apps/lex-book-trip-python/template.yaml | 23 - examples/apps/lex-book-trip/index.js | 401 -- examples/apps/lex-book-trip/license.txt | 201 - examples/apps/lex-book-trip/readme | 38 - examples/apps/lex-book-trip/requirements.txt | 1 - examples/apps/lex-book-trip/template.yaml | 23 - .../lambda_function.py | 508 -- .../lex-make-appointment-python/license.txt | 201 - .../apps/lex-make-appointment-python/readme | 38 - .../requirements.txt | 1 - .../lex-make-appointment-python/template.yaml | 23 - examples/apps/lex-make-appointment/index.js | 446 -- .../apps/lex-make-appointment/license.txt | 201 - examples/apps/lex-make-appointment/readme | 38 - .../apps/lex-make-appointment/template.yaml | 23 - .../lambda_function.py | 191 - .../apps/lex-order-flowers-python/license.txt | 201 - examples/apps/lex-order-flowers-python/readme | 38 - .../lex-order-flowers-python/requirements.txt | 1 - .../lex-order-flowers-python/template.yaml | 21 - examples/apps/lex-order-flowers/index.js | 173 - examples/apps/lex-order-flowers/license.txt | 201 - examples/apps/lex-order-flowers/readme | 38 - examples/apps/lex-order-flowers/template.yaml | 21 - .../readme | 3 - .../lambda_function.py | 213 - .../license.txt | 201 - .../readme | 38 - .../requirements.txt | 1 - .../template.yaml | 28 - .../lambda_function.py | 44 - .../template.yaml | 27 - .../lambda_function.py | 46 - .../template.yaml | 40 - .../test-output.log | 70 - .../test-payload.json | 5 - .../test.sh | 19 - .../apps/microservice-http-endpoint/index.js | 47 - .../microservice-http-endpoint/package.json | 8 - .../microservice-http-endpoint/template.yaml | 27 - examples/apps/node-exec/index.js | 17 - examples/apps/node-exec/lambda_function.py | 69 - .../response/detect-faces-response.json | 1 - examples/apps/node-exec/template.yaml | 27 - examples/apps/node-exec/testEvent.json | 3 - .../rekognition-python/lambda_function.py | 69 - .../response/detect-faces-response.json | 1 - .../apps/rekognition-python/template.yaml | 38 - .../s3-get-object-python/lambda_function.py | 25 - .../apps/s3-get-object-python/template.yaml | 36 - examples/apps/s3-get-object-python3/index.js | 78 - .../s3-get-object-python3/lambda_function.py | 24 - .../lib/mysplunklogger.js | 92 - .../apps/s3-get-object-python3/template.yaml | 36 - examples/apps/s3-get-object/index.js | 31 - examples/apps/s3-get-object/template.yaml | 35 - examples/apps/s3-get-object/testEvent.json | 38 - .../apps/ses-notification-nodejs/index.js | 43 - .../ses-notification-nodejs/template.yaml | 21 - .../lambda_function.py | 47 - .../ses-notification-python/template.yaml | 21 - examples/apps/simple-mobile-backend/index.js | 52 - .../apps/simple-mobile-backend/template.yaml | 19 - .../lambda_function.py | 80 - .../slack-echo-command-python/template.yaml | 32 - examples/apps/slack-echo-command/index.js | 91 - .../apps/slack-echo-command/template.yaml | 32 - .../sns-message-python/lambda_function.py | 12 - .../apps/sns-message-python/template.yaml | 21 - examples/apps/sns-message/index.js | 10 - examples/apps/sns-message/template.yaml | 21 - .../splunk-cloudwatch-logs-processor/index.js | 78 - .../lib/mysplunklogger.js | 92 - .../template.yaml | 28 - .../splunk-dynamodb-stream-processor/index.js | 65 - .../lib/mysplunklogger.js | 92 - .../template.yaml | 52 - .../index.js | 95 - .../lib/mysplunklogger.js | 94 - .../template.yaml | 40 - .../index.js | 86 - .../lib/mysplunklogger.js | 94 - .../template.yaml | 38 - examples/apps/splunk-iot-processor/index.js | 64 - .../lib/mysplunklogger.js | 92 - .../apps/splunk-iot-processor/template.yaml | 24 - .../splunk-kinesis-stream-processor/index.js | 80 - .../lib/mysplunklogger.js | 92 - .../template.yaml | 38 - examples/apps/splunk-logging/index.js | 67 - .../apps/splunk-logging/lib/mysplunklogger.js | 92 - examples/apps/splunk-logging/template.yaml | 30 - examples/apps/sqs-poller/index.js | 77 - examples/apps/sqs-poller/template.yaml | 27 - .../lambda_function.py | 5 - .../step-functions-error-python/template.yaml | 18 - examples/apps/step-functions-error/index.js | 12 - .../apps/step-functions-error/template.yaml | 18 - .../lambda_function.py | 30 - .../step-functions-send-to-sns/template.yaml | 19 - examples/apps/sumologic-process-logs/index.js | 215 - .../apps/sumologic-process-logs/template.yaml | 16 - examples/apps/twilio-conference/index.js | 53 - examples/apps/twilio-conference/template.yaml | 22 - examples/apps/twilio-forward/index.js | 39 - examples/apps/twilio-forward/template.yaml | 22 - examples/apps/twilio-menu/index.js | 59 - examples/apps/twilio-menu/template.yaml | 24 - .../apps/twilio-simple-blueprint/index.js | 19 - .../twilio-simple-blueprint/template.yaml | 22 - .../vpn-conn-monitor/monitor_vpn_lambda.py | 78 - examples/apps/vpn-conn-monitor/template.yaml | 16 - 383 files changed, 34728 deletions(-) delete mode 100644 examples/apps/alexa-skill-kit-sdk-factskill/index.js delete mode 100644 examples/apps/alexa-skill-kit-sdk-factskill/package.json delete mode 100644 examples/apps/alexa-skill-kit-sdk-factskill/template.yaml delete mode 100644 examples/apps/alexa-skill-kit-sdk-howtoskill/index.js delete mode 100644 examples/apps/alexa-skill-kit-sdk-howtoskill/package.json delete mode 100644 examples/apps/alexa-skill-kit-sdk-howtoskill/recipes.js delete mode 100644 examples/apps/alexa-skill-kit-sdk-howtoskill/template.yaml delete mode 100644 examples/apps/alexa-skill-kit-sdk-triviaskill/index.js delete mode 100644 examples/apps/alexa-skill-kit-sdk-triviaskill/package.json delete mode 100644 examples/apps/alexa-skill-kit-sdk-triviaskill/question.js delete mode 100644 examples/apps/alexa-skill-kit-sdk-triviaskill/template.yaml delete mode 100644 examples/apps/alexa-skills-kit-color-expert-python/index.js delete mode 100644 examples/apps/alexa-skills-kit-color-expert-python/lambda_function.py delete mode 100644 examples/apps/alexa-skills-kit-color-expert-python/package.json delete mode 100644 examples/apps/alexa-skills-kit-color-expert-python/question.js delete mode 100644 examples/apps/alexa-skills-kit-color-expert-python/template.yaml delete mode 100644 examples/apps/alexa-skills-kit-color-expert/index.js delete mode 100644 examples/apps/alexa-skills-kit-color-expert/package.json delete mode 100644 examples/apps/alexa-skills-kit-color-expert/question.js delete mode 100644 examples/apps/alexa-skills-kit-color-expert/template.yaml delete mode 100644 examples/apps/alexa-skills-kit-color-expert/testEvent.json delete mode 100644 examples/apps/alexa-smart-home-skill-adapter/index.js delete mode 100644 examples/apps/alexa-smart-home-skill-adapter/package.json delete mode 100644 examples/apps/alexa-smart-home-skill-adapter/recipes.js delete mode 100644 examples/apps/alexa-smart-home-skill-adapter/template.yaml delete mode 100644 examples/apps/algorithmia/index.js delete mode 100644 examples/apps/algorithmia/package.json delete mode 100644 examples/apps/algorithmia/template.yaml delete mode 100644 examples/apps/api-gateway-authorizer-nodejs/index.js delete mode 100644 examples/apps/api-gateway-authorizer-nodejs/package.json delete mode 100644 examples/apps/api-gateway-authorizer-nodejs/template.yaml delete mode 100644 examples/apps/api-gateway-authorizer-python/lambda_function.py delete mode 100644 examples/apps/api-gateway-authorizer-python/template.yaml delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/README.md delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/cors-config.json delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/cors-util.js delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/cors-util.test.js delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/package-lock.json delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/package.json delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/routes/root.js delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/routes/test.js delete mode 100644 examples/apps/api-gateway-multiple-origin-cors/template.yaml delete mode 100644 examples/apps/cfn-look-up-ami-ids/index.js delete mode 100644 examples/apps/cfn-look-up-ami-ids/package.json delete mode 100644 examples/apps/cfn-look-up-ami-ids/template.yaml delete mode 100644 examples/apps/cfn-stack-outputs/index.js delete mode 100644 examples/apps/cfn-stack-outputs/package.json delete mode 100644 examples/apps/cfn-stack-outputs/template.yaml delete mode 100644 examples/apps/cloudfront-ab-test/index.js delete mode 100644 examples/apps/cloudfront-ab-test/template.yaml delete mode 100644 examples/apps/cloudfront-ab-test/testEvent.json delete mode 100644 examples/apps/cloudfront-access-request-in-response/index.js delete mode 100644 examples/apps/cloudfront-access-request-in-response/template.yaml delete mode 100644 examples/apps/cloudfront-access-request-in-response/testEvent.json delete mode 100644 examples/apps/cloudfront-http-redirect/index.js delete mode 100644 examples/apps/cloudfront-http-redirect/template.yaml delete mode 100644 examples/apps/cloudfront-modify-querystring/index.js delete mode 100644 examples/apps/cloudfront-modify-querystring/template.yaml delete mode 100644 examples/apps/cloudfront-modify-querystring/testEvent.json delete mode 100644 examples/apps/cloudfront-modify-response-header/index.js delete mode 100644 examples/apps/cloudfront-modify-response-header/template.yaml delete mode 100644 examples/apps/cloudfront-modify-response-header/testEvent.json delete mode 100644 examples/apps/cloudfront-multiple-remote-calls-aggregate-response/index.js delete mode 100644 examples/apps/cloudfront-multiple-remote-calls-aggregate-response/template.yaml delete mode 100644 examples/apps/cloudfront-multiple-remote-calls-aggregate-response/testEvent.json delete mode 100644 examples/apps/cloudfront-redirect-on-viewer-country/index.js delete mode 100644 examples/apps/cloudfront-redirect-on-viewer-country/template.yaml delete mode 100644 examples/apps/cloudfront-redirect-on-viewer-country/testEvent.json delete mode 100644 examples/apps/cloudfront-redirect-unauthenticated-users/index.js delete mode 100644 examples/apps/cloudfront-redirect-unauthenticated-users/package.json delete mode 100644 examples/apps/cloudfront-redirect-unauthenticated-users/template.yaml delete mode 100644 examples/apps/cloudfront-redirect-unauthenticated-users/testEvent.json delete mode 100644 examples/apps/cloudfront-response-generation/index.js delete mode 100644 examples/apps/cloudfront-response-generation/template.yaml delete mode 100644 examples/apps/cloudfront-simple-remote-call/index.js delete mode 100644 examples/apps/cloudfront-simple-remote-call/template.yaml delete mode 100644 examples/apps/cloudfront-simple-remote-call/testEvent.json delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python/index.js delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python/lambda_function.py delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python/package.json delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python/template.yaml delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python3/index.js delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python3/lambda_function.py delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python3/package.json delete mode 100644 examples/apps/cloudwatch-alarm-to-slack-python3/template.yaml delete mode 100644 examples/apps/cloudwatch-alarm-to-slack/index.js delete mode 100644 examples/apps/cloudwatch-alarm-to-slack/package.json delete mode 100644 examples/apps/cloudwatch-alarm-to-slack/template.yaml delete mode 100644 examples/apps/cloudwatch-logs-process-data/index.js delete mode 100644 examples/apps/cloudwatch-logs-process-data/package.json delete mode 100644 examples/apps/cloudwatch-logs-process-data/template.yaml delete mode 100644 examples/apps/cloudwatch-logs-to-loggly/index.js delete mode 100644 examples/apps/cloudwatch-logs-to-loggly/package.json delete mode 100644 examples/apps/cloudwatch-logs-to-loggly/template.yaml delete mode 100644 examples/apps/cognito-sync-trigger/index.js delete mode 100644 examples/apps/cognito-sync-trigger/package.json delete mode 100644 examples/apps/cognito-sync-trigger/template.yaml delete mode 100644 examples/apps/config-rule-change-triggered/index.js delete mode 100644 examples/apps/config-rule-change-triggered/template.yaml delete mode 100644 examples/apps/config-rule-periodic/index.js delete mode 100644 examples/apps/config-rule-periodic/template.yaml delete mode 100644 examples/apps/datadog-process-rds-metrics/lambda_function.py delete mode 100644 examples/apps/datadog-process-rds-metrics/template.yaml delete mode 100644 examples/apps/dynamodb-process-stream-python/lambda_function.py delete mode 100644 examples/apps/dynamodb-process-stream-python/template.yaml delete mode 100644 examples/apps/dynamodb-process-stream-python3/index.js delete mode 100644 examples/apps/dynamodb-process-stream-python3/lambda_function.py delete mode 100644 examples/apps/dynamodb-process-stream-python3/lib/mysplunklogger.js delete mode 100644 examples/apps/dynamodb-process-stream-python3/template.yaml delete mode 100644 examples/apps/dynamodb-process-stream/index.js delete mode 100644 examples/apps/dynamodb-process-stream/template.yaml delete mode 100755 examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/index.js delete mode 100755 examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/iotdata.js delete mode 100755 examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/lambda.js delete mode 100755 examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/secretsmanager.js delete mode 100755 examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/util.js delete mode 100644 examples/apps/greengrass-hello-world-nodejs/index.js delete mode 100644 examples/apps/greengrass-hello-world-nodejs/license/license.txt delete mode 100644 examples/apps/greengrass-hello-world-nodejs/template.yaml delete mode 100644 examples/apps/greengrass-hello-world/greengrassHelloWorld.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/IoTDataPlane.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/Lambda.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/SecretsManager.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/__init__.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/client.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/utils/__init__.py delete mode 100755 examples/apps/greengrass-hello-world/greengrasssdk/utils/testing.py delete mode 100644 examples/apps/greengrass-hello-world/license/license.txt delete mode 100644 examples/apps/greengrass-hello-world/template.yaml delete mode 100644 examples/apps/hello-world-python/lambda_function.py delete mode 100644 examples/apps/hello-world-python/license.txt delete mode 100644 examples/apps/hello-world-python/readme delete mode 100644 examples/apps/hello-world-python/template.yaml delete mode 100644 examples/apps/hello-world-python3/lambda_function.py delete mode 100644 examples/apps/hello-world-python3/license.txt delete mode 100644 examples/apps/hello-world-python3/readme delete mode 100644 examples/apps/hello-world-python3/template.yaml delete mode 100644 examples/apps/hello-world/index.js delete mode 100644 examples/apps/hello-world/license.txt delete mode 100644 examples/apps/hello-world/readme delete mode 100644 examples/apps/hello-world/template.yaml delete mode 100644 examples/apps/hello-world/testEvent.json delete mode 100644 examples/apps/https-request/index.js delete mode 100644 examples/apps/https-request/license.txt delete mode 100644 examples/apps/https-request/readme delete mode 100644 examples/apps/https-request/template.yaml delete mode 100644 examples/apps/image-processing-service/index.js delete mode 100644 examples/apps/image-processing-service/license.txt delete mode 100644 examples/apps/image-processing-service/readme delete mode 100644 examples/apps/image-processing-service/template.yaml delete mode 100644 examples/apps/inbound-ses-spam-filter-python/lambda_function.py delete mode 100644 examples/apps/inbound-ses-spam-filter-python/license.txt delete mode 100644 examples/apps/inbound-ses-spam-filter-python/readme delete mode 100644 examples/apps/inbound-ses-spam-filter-python/requirements.txt delete mode 100644 examples/apps/inbound-ses-spam-filter-python/template.yaml delete mode 100644 examples/apps/inbound-ses-spam-filter/index.js delete mode 100644 examples/apps/inbound-ses-spam-filter/license.txt delete mode 100644 examples/apps/inbound-ses-spam-filter/readme delete mode 100644 examples/apps/inbound-ses-spam-filter/template.yaml delete mode 100644 examples/apps/inspector-scheduled-run/index.js delete mode 100644 examples/apps/inspector-scheduled-run/license.txt delete mode 100644 examples/apps/inspector-scheduled-run/readme delete mode 100644 examples/apps/inspector-scheduled-run/template.yaml delete mode 100644 examples/apps/kinesis-analytics-process-compressed-record/index.js delete mode 100644 examples/apps/kinesis-analytics-process-compressed-record/license.txt delete mode 100644 examples/apps/kinesis-analytics-process-compressed-record/readme delete mode 100644 examples/apps/kinesis-analytics-process-compressed-record/template.yaml delete mode 100644 examples/apps/kinesis-analytics-process-compressed-record/testEvent.json delete mode 100644 examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/__init__.py delete mode 100644 examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/deaggregator.py delete mode 100644 examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/kpl_pb2.py delete mode 100644 examples/apps/kinesis-analytics-process-kpl-record/lambda_function.py delete mode 100644 examples/apps/kinesis-analytics-process-kpl-record/requirements.txt delete mode 100644 examples/apps/kinesis-analytics-process-kpl-record/template.yaml delete mode 100644 examples/apps/kinesis-analytics-process-record-python/lambda_function.py delete mode 100644 examples/apps/kinesis-analytics-process-record-python/license.txt delete mode 100644 examples/apps/kinesis-analytics-process-record-python/readme delete mode 100644 examples/apps/kinesis-analytics-process-record-python/requirements.txt delete mode 100644 examples/apps/kinesis-analytics-process-record-python/template.yaml delete mode 100644 examples/apps/kinesis-analytics-process-record/index.js delete mode 100644 examples/apps/kinesis-analytics-process-record/license.txt delete mode 100644 examples/apps/kinesis-analytics-process-record/readme delete mode 100644 examples/apps/kinesis-analytics-process-record/template.yaml delete mode 100644 examples/apps/kinesis-analytics-process-record/testEvent.json delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv-python/lambda_function.py delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv-python/license.txt delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv-python/readme delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv-python/requirements.txt delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv-python/template.yaml delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv/index.js delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv/license.txt delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv/readme delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv/template.yaml delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-csv/testEvent.json delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json-python/lambda_function.py delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json-python/license.txt delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json-python/requirements.txt delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json-python/template.yaml delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json/index.js delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json/license.txt delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json/template.yaml delete mode 100644 examples/apps/kinesis-firehose-apachelog-to-json/testEvent.json delete mode 100644 examples/apps/kinesis-firehose-cloudwatch-logs-processor/index.js delete mode 100644 examples/apps/kinesis-firehose-cloudwatch-logs-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/kinesis-firehose-cloudwatch-logs-processor/template.yaml delete mode 100644 examples/apps/kinesis-firehose-cloudwatch-logs-processor/testEvent.json delete mode 100644 examples/apps/kinesis-firehose-process-record-python/lambda_function.py delete mode 100644 examples/apps/kinesis-firehose-process-record-python/license.txt delete mode 100644 examples/apps/kinesis-firehose-process-record-python/readme delete mode 100644 examples/apps/kinesis-firehose-process-record-python/requirements.txt delete mode 100644 examples/apps/kinesis-firehose-process-record-python/template.yaml delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source-python/lambda_function.py delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source-python/license.txt delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source-python/readme delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source-python/requirements.txt delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source-python/template.yaml delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source/index.js delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source/license.txt delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source/readme delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source/template.yaml delete mode 100644 examples/apps/kinesis-firehose-process-record-streams-as-source/testEvent.json delete mode 100644 examples/apps/kinesis-firehose-process-record/index.js delete mode 100644 examples/apps/kinesis-firehose-process-record/license.txt delete mode 100644 examples/apps/kinesis-firehose-process-record/readme delete mode 100644 examples/apps/kinesis-firehose-process-record/template.yaml delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv-python/lambda_function.py delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv-python/license.txt delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv-python/readme delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv-python/requirements.txt delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv-python/template.yaml delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv/index.js delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv/license.txt delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv/readme delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv/template.yaml delete mode 100644 examples/apps/kinesis-firehose-syslog-to-csv/testEvent.json delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json-python/lambda_function.py delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json-python/license.txt delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json-python/readme delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json-python/requirements.txt delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json-python/template.yaml delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json/index.js delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json/license.txt delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json/readme delete mode 100644 examples/apps/kinesis-firehose-syslog-to-json/template.yaml delete mode 100644 examples/apps/kinesis-process-record-python/lambda_function.py delete mode 100644 examples/apps/kinesis-process-record-python/license.txt delete mode 100644 examples/apps/kinesis-process-record-python/readme delete mode 100644 examples/apps/kinesis-process-record-python/requirements.txt delete mode 100644 examples/apps/kinesis-process-record-python/template.yaml delete mode 100644 examples/apps/kinesis-process-record/index.js delete mode 100644 examples/apps/kinesis-process-record/license.txt delete mode 100644 examples/apps/kinesis-process-record/readme delete mode 100644 examples/apps/kinesis-process-record/template.yaml delete mode 100644 examples/apps/lambda-canary-python3/lambda_function.py delete mode 100644 examples/apps/lambda-canary-python3/license.txt delete mode 100644 examples/apps/lambda-canary-python3/readme delete mode 100644 examples/apps/lambda-canary-python3/requirements.txt delete mode 100644 examples/apps/lambda-canary-python3/template.yaml delete mode 100644 examples/apps/lambda-canary/lambda_function.py delete mode 100644 examples/apps/lambda-canary/license.txt delete mode 100644 examples/apps/lambda-canary/readme delete mode 100644 examples/apps/lambda-canary/requirements.txt delete mode 100644 examples/apps/lambda-canary/template.yaml delete mode 100644 examples/apps/lambda-test-harness/index.js delete mode 100644 examples/apps/lambda-test-harness/license.txt delete mode 100644 examples/apps/lambda-test-harness/readme delete mode 100644 examples/apps/lambda-test-harness/template.yaml delete mode 100644 examples/apps/lex-book-trip-python/lambda_function.py delete mode 100644 examples/apps/lex-book-trip-python/license.txt delete mode 100644 examples/apps/lex-book-trip-python/readme delete mode 100644 examples/apps/lex-book-trip-python/requirements.txt delete mode 100644 examples/apps/lex-book-trip-python/template.yaml delete mode 100644 examples/apps/lex-book-trip/index.js delete mode 100644 examples/apps/lex-book-trip/license.txt delete mode 100644 examples/apps/lex-book-trip/readme delete mode 100644 examples/apps/lex-book-trip/requirements.txt delete mode 100644 examples/apps/lex-book-trip/template.yaml delete mode 100644 examples/apps/lex-make-appointment-python/lambda_function.py delete mode 100644 examples/apps/lex-make-appointment-python/license.txt delete mode 100644 examples/apps/lex-make-appointment-python/readme delete mode 100644 examples/apps/lex-make-appointment-python/requirements.txt delete mode 100644 examples/apps/lex-make-appointment-python/template.yaml delete mode 100644 examples/apps/lex-make-appointment/index.js delete mode 100644 examples/apps/lex-make-appointment/license.txt delete mode 100644 examples/apps/lex-make-appointment/readme delete mode 100644 examples/apps/lex-make-appointment/template.yaml delete mode 100644 examples/apps/lex-order-flowers-python/lambda_function.py delete mode 100644 examples/apps/lex-order-flowers-python/license.txt delete mode 100644 examples/apps/lex-order-flowers-python/readme delete mode 100644 examples/apps/lex-order-flowers-python/requirements.txt delete mode 100644 examples/apps/lex-order-flowers-python/template.yaml delete mode 100644 examples/apps/lex-order-flowers/index.js delete mode 100644 examples/apps/lex-order-flowers/license.txt delete mode 100644 examples/apps/lex-order-flowers/readme delete mode 100644 examples/apps/lex-order-flowers/template.yaml delete mode 100644 examples/apps/logicmonitor-send-cloudwatch-events/readme delete mode 100644 examples/apps/logicmonitor-send-eventbridge-events/lambda_function.py delete mode 100644 examples/apps/logicmonitor-send-eventbridge-events/license.txt delete mode 100644 examples/apps/logicmonitor-send-eventbridge-events/readme delete mode 100644 examples/apps/logicmonitor-send-eventbridge-events/requirements.txt delete mode 100644 examples/apps/logicmonitor-send-eventbridge-events/template.yaml delete mode 100644 examples/apps/microservice-http-endpoint-python/lambda_function.py delete mode 100644 examples/apps/microservice-http-endpoint-python/template.yaml delete mode 100644 examples/apps/microservice-http-endpoint-python3/lambda_function.py delete mode 100644 examples/apps/microservice-http-endpoint-python3/template.yaml delete mode 100644 examples/apps/microservice-http-endpoint-python3/test-output.log delete mode 100644 examples/apps/microservice-http-endpoint-python3/test-payload.json delete mode 100755 examples/apps/microservice-http-endpoint-python3/test.sh delete mode 100644 examples/apps/microservice-http-endpoint/index.js delete mode 100644 examples/apps/microservice-http-endpoint/package.json delete mode 100644 examples/apps/microservice-http-endpoint/template.yaml delete mode 100644 examples/apps/node-exec/index.js delete mode 100644 examples/apps/node-exec/lambda_function.py delete mode 100644 examples/apps/node-exec/response/detect-faces-response.json delete mode 100644 examples/apps/node-exec/template.yaml delete mode 100644 examples/apps/node-exec/testEvent.json delete mode 100644 examples/apps/rekognition-python/lambda_function.py delete mode 100644 examples/apps/rekognition-python/response/detect-faces-response.json delete mode 100644 examples/apps/rekognition-python/template.yaml delete mode 100644 examples/apps/s3-get-object-python/lambda_function.py delete mode 100644 examples/apps/s3-get-object-python/template.yaml delete mode 100644 examples/apps/s3-get-object-python3/index.js delete mode 100644 examples/apps/s3-get-object-python3/lambda_function.py delete mode 100644 examples/apps/s3-get-object-python3/lib/mysplunklogger.js delete mode 100644 examples/apps/s3-get-object-python3/template.yaml delete mode 100644 examples/apps/s3-get-object/index.js delete mode 100644 examples/apps/s3-get-object/template.yaml delete mode 100644 examples/apps/s3-get-object/testEvent.json delete mode 100644 examples/apps/ses-notification-nodejs/index.js delete mode 100644 examples/apps/ses-notification-nodejs/template.yaml delete mode 100644 examples/apps/ses-notification-python/lambda_function.py delete mode 100644 examples/apps/ses-notification-python/template.yaml delete mode 100644 examples/apps/simple-mobile-backend/index.js delete mode 100644 examples/apps/simple-mobile-backend/template.yaml delete mode 100644 examples/apps/slack-echo-command-python/lambda_function.py delete mode 100644 examples/apps/slack-echo-command-python/template.yaml delete mode 100644 examples/apps/slack-echo-command/index.js delete mode 100644 examples/apps/slack-echo-command/template.yaml delete mode 100644 examples/apps/sns-message-python/lambda_function.py delete mode 100644 examples/apps/sns-message-python/template.yaml delete mode 100644 examples/apps/sns-message/index.js delete mode 100644 examples/apps/sns-message/template.yaml delete mode 100644 examples/apps/splunk-cloudwatch-logs-processor/index.js delete mode 100644 examples/apps/splunk-cloudwatch-logs-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-cloudwatch-logs-processor/template.yaml delete mode 100644 examples/apps/splunk-dynamodb-stream-processor/index.js delete mode 100644 examples/apps/splunk-dynamodb-stream-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-dynamodb-stream-processor/template.yaml delete mode 100644 examples/apps/splunk-elb-application-access-logs-processor/index.js delete mode 100644 examples/apps/splunk-elb-application-access-logs-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-elb-application-access-logs-processor/template.yaml delete mode 100644 examples/apps/splunk-elb-classic-access-logs-processor/index.js delete mode 100644 examples/apps/splunk-elb-classic-access-logs-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-elb-classic-access-logs-processor/template.yaml delete mode 100644 examples/apps/splunk-iot-processor/index.js delete mode 100644 examples/apps/splunk-iot-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-iot-processor/template.yaml delete mode 100644 examples/apps/splunk-kinesis-stream-processor/index.js delete mode 100644 examples/apps/splunk-kinesis-stream-processor/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-kinesis-stream-processor/template.yaml delete mode 100644 examples/apps/splunk-logging/index.js delete mode 100644 examples/apps/splunk-logging/lib/mysplunklogger.js delete mode 100644 examples/apps/splunk-logging/template.yaml delete mode 100644 examples/apps/sqs-poller/index.js delete mode 100644 examples/apps/sqs-poller/template.yaml delete mode 100644 examples/apps/step-functions-error-python/lambda_function.py delete mode 100644 examples/apps/step-functions-error-python/template.yaml delete mode 100644 examples/apps/step-functions-error/index.js delete mode 100644 examples/apps/step-functions-error/template.yaml delete mode 100644 examples/apps/step-functions-send-to-sns/lambda_function.py delete mode 100644 examples/apps/step-functions-send-to-sns/template.yaml delete mode 100644 examples/apps/sumologic-process-logs/index.js delete mode 100644 examples/apps/sumologic-process-logs/template.yaml delete mode 100644 examples/apps/twilio-conference/index.js delete mode 100644 examples/apps/twilio-conference/template.yaml delete mode 100644 examples/apps/twilio-forward/index.js delete mode 100644 examples/apps/twilio-forward/template.yaml delete mode 100644 examples/apps/twilio-menu/index.js delete mode 100644 examples/apps/twilio-menu/template.yaml delete mode 100644 examples/apps/twilio-simple-blueprint/index.js delete mode 100644 examples/apps/twilio-simple-blueprint/template.yaml delete mode 100644 examples/apps/vpn-conn-monitor/monitor_vpn_lambda.py delete mode 100644 examples/apps/vpn-conn-monitor/template.yaml diff --git a/examples/apps/alexa-skill-kit-sdk-factskill/index.js b/examples/apps/alexa-skill-kit-sdk-factskill/index.js deleted file mode 100644 index 5a204d2222..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-factskill/index.js +++ /dev/null @@ -1,146 +0,0 @@ -/* eslint-disable func-names */ -/* eslint quote-props: ["error", "consistent"]*/ -/** - * This sample demonstrates a simple skill built with the Amazon Alexa Skills - * nodejs skill development kit. - * This sample supports multiple lauguages. (en-US, en-GB, de-DE). - * The Intent Schema, Custom Slots and Sample Utterances for this skill, as well - * as testing instructions are located at https://github.com/alexa/skill-sample-nodejs-fact - **/ - -'use strict'; - -const Alexa = require('alexa-sdk'); - -const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL). - -const languageStrings = { - 'en': { - translation: { - FACTS: [ - 'A year on Mercury is just 88 days long.', - 'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.', - 'Venus rotates anti-clockwise, possibly because of a collision in the past with an asteroid.', - 'On Mars, the Sun appears about half the size as it does on Earth.', - 'Earth is the only planet not named after a god.', - 'Jupiter has the shortest day of all the planets.', - 'The Milky Way galaxy will collide with the Andromeda Galaxy in about 5 billion years.', - 'The Sun contains 99.86% of the mass in the Solar System.', - 'The Sun is an almost perfect sphere.', - 'A total solar eclipse can happen once every 1 to 2 years. This makes them a rare event.', - 'Saturn radiates two and a half times more energy into space than it receives from the sun.', - 'The temperature inside the Sun can reach 15 million degrees Celsius.', - 'The Moon is moving approximately 3.8 cm away from our planet every year.', - ], - SKILL_NAME: 'Space Facts', - GET_FACT_MESSAGE: "Here's your fact: ", - HELP_MESSAGE: 'You can say tell me a space fact, or, you can say exit... What can I help you with?', - HELP_REPROMPT: 'What can I help you with?', - STOP_MESSAGE: 'Goodbye!', - }, - }, - 'en-US': { - translation: { - FACTS: [ - 'A year on Mercury is just 88 days long.', - 'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.', - 'Venus rotates counter-clockwise, possibly because of a collision in the past with an asteroid.', - 'On Mars, the Sun appears about half the size as it does on Earth.', - 'Earth is the only planet not named after a god.', - 'Jupiter has the shortest day of all the planets.', - 'The Milky Way galaxy will collide with the Andromeda Galaxy in about 5 billion years.', - 'The Sun contains 99.86% of the mass in the Solar System.', - 'The Sun is an almost perfect sphere.', - 'A total solar eclipse can happen once every 1 to 2 years. This makes them a rare event.', - 'Saturn radiates two and a half times more energy into space than it receives from the sun.', - 'The temperature inside the Sun can reach 15 million degrees Celsius.', - 'The Moon is moving approximately 3.8 cm away from our planet every year.', - ], - SKILL_NAME: 'American Space Facts', - }, - }, - 'en-GB': { - translation: { - FACTS: [ - 'A year on Mercury is just 88 days long.', - 'Despite being farther from the Sun, Venus experiences higher temperatures than Mercury.', - 'Venus rotates anti-clockwise, possibly because of a collision in the past with an asteroid.', - 'On Mars, the Sun appears about half the size as it does on Earth.', - 'Earth is the only planet not named after a god.', - 'Jupiter has the shortest day of all the planets.', - 'The Milky Way galaxy will collide with the Andromeda Galaxy in about 5 billion years.', - 'The Sun contains 99.86% of the mass in the Solar System.', - 'The Sun is an almost perfect sphere.', - 'A total solar eclipse can happen once every 1 to 2 years. This makes them a rare event.', - 'Saturn radiates two and a half times more energy into space than it receives from the sun.', - 'The temperature inside the Sun can reach 15 million degrees Celsius.', - 'The Moon is moving approximately 3.8 cm away from our planet every year.', - ], - SKILL_NAME: 'British Space Facts', - }, - }, - 'de': { - translation: { - FACTS: [ - 'Ein Jahr dauert auf dem Merkur nur 88 Tage.', - 'Die Venus ist zwar weiter von der Sonne entfernt, hat aber höhere Temperaturen als Merkur.', - 'Venus dreht sich entgegen dem Uhrzeigersinn, möglicherweise aufgrund eines früheren Zusammenstoßes mit einem Asteroiden.', - 'Auf dem Mars erscheint die Sonne nur halb so groß wie auf der Erde.', - 'Die Erde ist der einzige Planet, der nicht nach einem Gott benannt ist.', - 'Jupiter hat den kürzesten Tag aller Planeten.', - 'Die Milchstraßengalaxis wird in etwa 5 Milliarden Jahren mit der Andromeda-Galaxis zusammenstoßen.', - 'Die Sonne macht rund 99,86 % der Masse im Sonnensystem aus.', - 'Die Sonne ist eine fast perfekte Kugel.', - 'Eine Sonnenfinsternis kann alle ein bis zwei Jahre eintreten. Sie ist daher ein seltenes Ereignis.', - 'Der Saturn strahlt zweieinhalb mal mehr Energie in den Weltraum aus als er von der Sonne erhält.', - 'Die Temperatur in der Sonne kann 15 Millionen Grad Celsius erreichen.', - 'Der Mond entfernt sich von unserem Planeten etwa 3,8 cm pro Jahr.', - ], - SKILL_NAME: 'Weltraumwissen auf Deutsch', - GET_FACT_MESSAGE: 'Hier sind deine Fakten: ', - HELP_MESSAGE: 'Du kannst sagen, „Nenne mir einen Fakt über den Weltraum“, oder du kannst „Beenden“ sagen... Wie kann ich dir helfen?', - HELP_REPROMPT: 'Wie kann ich dir helfen?', - STOP_MESSAGE: 'Auf Wiedersehen!', - }, - }, -}; - -const handlers = { - 'LaunchRequest': function () { - this.emit('GetFact'); - }, - 'GetNewFactIntent': function () { - this.emit('GetFact'); - }, - 'GetFact': function () { - // Get a random space fact from the space facts list - // Use this.t() to get corresponding language data - const factArr = this.t('FACTS'); - const factIndex = Math.floor(Math.random() * factArr.length); - const randomFact = factArr[factIndex]; - - // Create speech output - const speechOutput = this.t('GET_FACT_MESSAGE') + randomFact; - this.emit(':tellWithCard', speechOutput, this.t('SKILL_NAME'), randomFact); - }, - 'AMAZON.HelpIntent': function () { - const speechOutput = this.t('HELP_MESSAGE'); - const reprompt = this.t('HELP_MESSAGE'); - this.emit(':ask', speechOutput, reprompt); - }, - 'AMAZON.CancelIntent': function () { - this.emit(':tell', this.t('STOP_MESSAGE')); - }, - 'AMAZON.StopIntent': function () { - this.emit(':tell', this.t('STOP_MESSAGE')); - }, -}; - -exports.handler = function (event, context) { - const alexa = Alexa.handler(event, context); - alexa.APP_ID = APP_ID; - // To enable string internationalization (i18n) features, set a resources object. - alexa.resources = languageStrings; - alexa.registerHandlers(handlers); - alexa.execute(); -}; diff --git a/examples/apps/alexa-skill-kit-sdk-factskill/package.json b/examples/apps/alexa-skill-kit-sdk-factskill/package.json deleted file mode 100644 index c4cbd5b911..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-factskill/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "alexa-skill-kit-sdk-factskill", - "version": "1.0.0", - "private": true, - "dependencies": { - "alexa-sdk": "^1.0.10" - } -} diff --git a/examples/apps/alexa-skill-kit-sdk-factskill/template.yaml b/examples/apps/alexa-skill-kit-sdk-factskill/template.yaml deleted file mode 100644 index bb5490f227..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-factskill/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrate a basic fact skill built with the ASK NodeJS SDK -Parameters: - TopicNameParameter: - Type: String -Resources: - alexaskillkitsdkfactskill: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Demonstrate a basic fact skill built with the ASK NodeJS SDK - MemorySize: 128 - Timeout: 7 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter diff --git a/examples/apps/alexa-skill-kit-sdk-howtoskill/index.js b/examples/apps/alexa-skill-kit-sdk-howtoskill/index.js deleted file mode 100644 index be7958ac72..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-howtoskill/index.js +++ /dev/null @@ -1,137 +0,0 @@ -/* eslint-disable func-names */ -/* eslint quote-props: ["error", "consistent"]*/ -/** - * This sample demonstrates a sample skill built with Amazon Alexa Skills nodejs - * skill development kit. - * This sample supports multiple languages (en-US, en-GB, de-GB). - * The Intent Schema, Custom Slot and Sample Utterances for this skill, as well - * as testing instructions are located at https://github.com/alexa/skill-sample-nodejs-howto - **/ - -'use strict'; - -const Alexa = require('alexa-sdk'); -const recipes = require('./recipes'); - -const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL). - -const languageStrings = { - 'en': { - translation: { - RECIPES: recipes.RECIPE_EN_US, - SKILL_NAME: 'Minecraft Helper', - WELCOME_MESSAGE: "Welcome to %s. You can ask a question like, what\'s the recipe for a chest? ... Now, what can I help you with?", - WELCOME_REPROMPT: 'For instructions on what you can say, please say help me.', - DISPLAY_CARD_TITLE: '%s - Recipe for %s.', - HELP_MESSAGE: "You can ask questions such as, what\'s the recipe, or, you can say exit...Now, what can I help you with?", - HELP_REPROMPT: "You can say things like, what\'s the recipe, or you can say exit...Now, what can I help you with?", - STOP_MESSAGE: 'Goodbye!', - RECIPE_REPEAT_MESSAGE: 'Try saying repeat.', - RECIPE_NOT_FOUND_MESSAGE: "I\'m sorry, I currently do not know ", - RECIPE_NOT_FOUND_WITH_ITEM_NAME: 'the recipe for %s. ', - RECIPE_NOT_FOUND_WITHOUT_ITEM_NAME: 'that recipe. ', - RECIPE_NOT_FOUND_REPROMPT: 'What else can I help with?', - }, - }, - 'en-US': { - translation: { - RECIPES: recipes.RECIPE_EN_US, - SKILL_NAME: 'American Minecraft Helper', - }, - }, - 'en-GB': { - translation: { - RECIPES: recipes.RECIPE_EN_GB, - SKILL_NAME: 'British Minecraft Helper', - }, - }, - 'de': { - translation: { - RECIPES: recipes.RECIPE_DE_DE, - SKILL_NAME: 'Assistent für Minecraft in Deutsch', - WELCOME_MESSAGE: 'Willkommen bei %s. Du kannst beispielsweise die Frage stellen: Welche Rezepte gibt es für eine Truhe? ... Nun, womit kann ich dir helfen?', - WELCOME_REPROMPT: 'Wenn du wissen möchtest, was du sagen kannst, sag einfach „Hilf mir“.', - DISPLAY_CARD_TITLE: '%s - Rezept für %s.', - HELP_MESSAGE: 'Du kannst beispielsweise Fragen stellen wie „Wie geht das Rezept für“ oder du kannst „Beenden“ sagen ... Wie kann ich dir helfen?', - HELP_REPROMPT: 'Du kannst beispielsweise Sachen sagen wie „Wie geht das Rezept für“ oder du kannst „Beenden“ sagen ... Wie kann ich dir helfen?', - STOP_MESSAGE: 'Auf Wiedersehen!', - RECIPE_REPEAT_MESSAGE: 'Sage einfach „Wiederholen“.', - RECIPE_NOT_FOUND_MESSAGE: 'Tut mir leid, ich kenne derzeit ', - RECIPE_NOT_FOUND_WITH_ITEM_NAME: 'das Rezept für %s nicht. ', - RECIPE_NOT_FOUND_WITHOUT_ITEM_NAME: 'dieses Rezept nicht. ', - RECIPE_NOT_FOUND_REPROMPT: 'Womit kann ich dir sonst helfen?', - }, - }, -}; - -const handlers = { - 'LaunchRequest': function () { - this.attributes.speechOutput = this.t('WELCOME_MESSAGE', this.t('SKILL_NAME')); - // If the user either does not reply to the welcome message or says something that is not - // understood, they will be prompted again with this text. - this.attributes.repromptSpeech = this.t('WELCOME_REPROMPT'); - this.emit(':ask', this.attributes.speechOutput, this.attributes.repromptSpeech); - }, - 'RecipeIntent': function () { - const itemSlot = this.event.request.intent.slots.Item; - let itemName; - if (itemSlot && itemSlot.value) { - itemName = itemSlot.value.toLowerCase(); - } - - const cardTitle = this.t('DISPLAY_CARD_TITLE', this.t('SKILL_NAME'), itemName); - const myRecipes = this.t('RECIPES'); - const recipe = myRecipes[itemName]; - - if (recipe) { - this.attributes.speechOutput = recipe; - this.attributes.repromptSpeech = this.t('RECIPE_REPEAT_MESSAGE'); - this.emit(':askWithCard', recipe, this.attributes.repromptSpeech, cardTitle, recipe); - } else { - let speechOutput = this.t('RECIPE_NOT_FOUND_MESSAGE'); - const repromptSpeech = this.t('RECIPE_NOT_FOUND_REPROMPT'); - if (itemName) { - speechOutput += this.t('RECIPE_NOT_FOUND_WITH_ITEM_NAME', itemName); - } else { - speechOutput += this.t('RECIPE_NOT_FOUND_WITHOUT_ITEM_NAME'); - } - speechOutput += repromptSpeech; - - this.attributes.speechOutput = speechOutput; - this.attributes.repromptSpeech = repromptSpeech; - - this.emit(':ask', speechOutput, repromptSpeech); - } - }, - 'AMAZON.HelpIntent': function () { - this.attributes.speechOutput = this.t('HELP_MESSAGE'); - this.attributes.repromptSpeech = this.t('HELP_REPROMPT'); - this.emit(':ask', this.attributes.speechOutput, this.attributes.repromptSpeech); - }, - 'AMAZON.RepeatIntent': function () { - this.emit(':ask', this.attributes.speechOutput, this.attributes.repromptSpeech); - }, - 'AMAZON.StopIntent': function () { - this.emit('SessionEndedRequest'); - }, - 'AMAZON.CancelIntent': function () { - this.emit('SessionEndedRequest'); - }, - 'SessionEndedRequest': function () { - this.emit(':tell', this.t('STOP_MESSAGE')); - }, - 'Unhandled': function () { - this.attributes.speechOutput = this.t('HELP_MESSAGE'); - this.attributes.repromptSpeech = this.t('HELP_REPROMPT'); - this.emit(':ask', this.attributes.speechOutput, this.attributes.repromptSpeech); - }, -}; - -exports.handler = function (event, context) { - const alexa = Alexa.handler(event, context); - alexa.APP_ID = APP_ID; - // To enable string internationalization (i18n) features, set a resources object. - alexa.resources = languageStrings; - alexa.registerHandlers(handlers); - alexa.execute(); -}; diff --git a/examples/apps/alexa-skill-kit-sdk-howtoskill/package.json b/examples/apps/alexa-skill-kit-sdk-howtoskill/package.json deleted file mode 100644 index a8fb34e653..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-howtoskill/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "alexa-skill-kit-sdk-howtoskill", - "version": "1.0.0", - "private": true, - "dependencies": { - "alexa-sdk": "^1.0.10" - } -} diff --git a/examples/apps/alexa-skill-kit-sdk-howtoskill/recipes.js b/examples/apps/alexa-skill-kit-sdk-howtoskill/recipes.js deleted file mode 100644 index 9611d3fa89..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-howtoskill/recipes.js +++ /dev/null @@ -1,1536 +0,0 @@ -/* eslint-disable func-names */ -/* eslint-disable max-len */ -/* eslint quote-props: ['error', 'consistent']*/ -module.exports = { - 'RECIPE_EN_GB': { - 'snow golem': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'pillar quartz block': 'A pillar of quartz can be obtained by placing a block of quartz on top of a block of quartz in mine craft.', - 'firework rocket': 'A firework rocket can be crafted by placing a firework star in the left middle square, a piece of paper in the center square, and gunpowder in the right middle square in a crafting table. Similar to a firework star, a firework rocket can have more gunpowder added in the bottom row to increase the duration of a rocket.', - 'rabbit stew': 'Rabbit stew can be crafted by placing cooked rabbit in the top middle square, a carrot in the middle left square, a baked potato in the center square, any type of mushroom in the middle right square, and a bowl in the bottom middle square.', - 'cauldron': 'A cauldron can be created by placing iron ingots in all squares but the top middle and very center squares in a crafting table.', - 'stone shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'red carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'book and quill': 'A book and quill can be crafted by placing a book in the middle left square, an ink sac in the very center square, and a feather in the bottom middle square in a crafting table.', - 'item frame': 'An item frame can be crafted by placing leather in the very center square, and eight sticks surrounding it.', - 'map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'sticky piston': 'A sticky piston can be crafted by placing a slime ball on top of a piston in a crafting window', - 'bread': 'Bread can be crafted by placing three wheat across a row in a crafting table.', - 'wooden pick ax': 'All types of pick axs can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'shears': 'Shears can be crafted by placing two Iron Ingots diagonal from each other.', - 'raw beef': 'Raw Beef will drop from the death of a Cow or Moo shrooms.', - 'smooth red sandstone': 'Smooth red sandstone can be crafted by placing four red sandstone in a two by two grid in a crafting window.', - 'prismarine crystals': 'Prismarine Crystals can be obtained by defeating Guardians and Elder Guardians.', - 'oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'wooden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'jungle fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'activator rail': 'An activator rail can be crafted by placing a red stone torch in the very center square, sticks above and beneath it, and then six iron ingots in the remaining squares in a crafting table.', - 'farmland': 'Farmland can be created by plowing the land with a hoe.', - 'gold ore': 'Gold ore can be obtained by breaking gold ore blocks with an iron pick ax or better', - 'andesite': 'Andesite can be mined with a pick ax or crafted by placing diorite next to cobblestone in a crafting table.', - 'rose red': 'Rose red can be crafted by placing a poppy into a crafting table.', - 'iron axe': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'light blue dye': 'Light blue dye can be crafted by placing lapis lazuli next to bone meal in a crafting window.', - 'gray dye': 'Gray dye can be crafted by placing bonemeal next to an ink sac in a crafting window', - 'blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'golden leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'dark oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'wither mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'spider eye': 'A spider eye is randomly dropped by killing spiders or witches.', - 'magenta stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'brown stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'pumpkin pie': 'A pumpkin pie can be crafted by placing a pumpkin in the left middle square, sugar in the very center square, and an egg in the bottom middle square in a crafting table.', - 'snowball': 'A snowball can be obtained by breaking snow with a shovel.', - 'juke box': 'A juke box is crafted by placing a diamond in the very center square and wood planks all around that in a crafting table', - 'sand': 'Sand can be obtained by breaking sand blocks.', - 'dead bush': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'brick slab': 'A brick slab can be crafted by placing three brick blocks in a row in a crafting table.', - 'lily pad': 'Lily pads can be found naturally on water in swamplands or underground lakes.', - 'leather pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'mossy cobblestone wall': 'A mossy cobblestone wall is crafted by placing six mossy cobblestone across the bottom two rows in a crafting table.', - 'eleven disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'purple stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'magenta stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'mall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'jungle wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diamond ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'empty map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'stone pressure plate': 'A stone pressure plate can be crafted by placing two smooth stone, next to each other, horizontally, in a crafting window.', - 'trapdoor': 'Trapdoors can be crafted with either wooden planks or iron ingots. To craft a wooden trapdoor, place wooden planks in all spaces in the bottom two rows. To craft an iron trapdoor, place iron ingots in a two by two grid in a crafting table.', - 'gold boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'red stone wire': 'Redstone wire is simply red stone placed on the floor.', - 'piston': 'A piston can be crafted by placing an iron ingot in the center square, red stone in the bottom middle square, wooden planks across the top row, and cobblestone in the remaining squares.', - 'white stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'sugar': 'Sugar can be obtained by placing sugar cane in a crafting window.', - 'chain mail chest plate': 'Chain mail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'feather': 'Feathers can be randomly obtained by killing chickens.', - 'light blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'stone pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'pink carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'monster spawner': 'Monster spawners can not be obtained without cheats in mine craft.', - 'golden carrot': 'A golden carrot can be crafted by placing a carrot in the very middle square and eight gold nuggets surrounding that.', - 'stick': 'A stick can be crafted by placing a wooden plank on top of a wooden plank in a crafting window.', - 'diamond block': 'A diamond block can be crafted by placing diamonds in every square in a crafting table.', - 'green stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cooked chicken': 'Raw Chicken can be cooked by smelting it in a furnace. Alternately, Cooked Chicken has a chance of dropping when a Chicken dies while on fire.', - 'thirteen disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'wooden trapdoor': 'A wooden trapdoor can be crafted by placing wooden planks in all spaces in the bottom two rows in a crafting table.', - 'oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'crafting bench': 'A crafting bench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'nether quartz ore': 'Nether quartz ore can be randomly found in the nether. To obtain the ore instead of nether quartz, you will need to use a silk touch pick ax.', - 'golden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stone hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'coal ore': 'Coal ore can be obtained by breaking a coal ore block with a pick ax that is enchanted with silk touch', - 'dark oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 't.n.t.': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'brick': 'A brick can be crafted by smelting clay in a furnace.', - 'potato': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'orange carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'ink sack': 'An ink sack can be obtained by killing a squid.', - 'red stone': 'Redstone can be obtained by breaking red stone ore with an iron pick ax or better.', - 'dark oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diorite': 'Diorite can be mined with a pick ax or crafted by combining cobblestone and nether quartz in a two by two grid in a crafting table.', - 'workbench': 'A workbench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'jungle fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'magenta wool': 'Magenta wool can be crafted by placing magenta dye next to any color wool in a crafting window.', - 'dirt': 'Dirt can be obtained by breaking grass or dirt with a shovel.', - 'armor stand': 'An Armor Stand can be crafted with six sticks and one stone slab. Take three sticks and place it across the first row. Take the remaining three sticks and place one each in the bottom left, bottom right, and center middle. Place the stone slab in the bottom middle.', - 'cooked fish': 'Cooked fish is obtained by cooking fish in a furnace.', - 'lever': 'A lever can be crafted by placing a stick on top of cobblestone in a crafting window.', - 'leash': 'A leash can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'cooked rabbit': 'Cooked rabbit can be obtained by cooking raw rabbit in a furnace. Alternately, Cooked Rabbit has a chance of dropping when a Rabbit dies while on fire.', - 'jungle wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with hopper': 'A Mine cart With a Hopper can be crafted by placing a Hopper on top of a Mine cart in a crafting table.', - 'fermented spider eye': 'Fermented spider eye can be obtained by placing a brown mushroom in the middle left square, sugar in the very center square, and a spider eye in the bottom middle square in a crafting table.', - 'raw fish': 'Raw fish is randomly obtained by fishing.', - 'brown stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'sign': 'A sign is crafted by placing wooden planks in the top two rows and a stick in the bottom middle square.', - 't.n.t': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'hopper': 'A hopper can be crafted by placing a chest in the very center square, and then iron ingots in every square but the top middle, bottom left, and bottom right squares in a crafting grid.', - 'blaze rod': 'Blaze rods can be randomly obtained by killing blazes.', - 'red stone comparator': 'A red stone comparator can be crafted by placing three smooth stone across the bottom row, a nether quartz in the center square, and three red stone torches surrounding the nether quartz in a crafting table.', - 'bone': 'Bones can be obtained by killing skeletons.', - 'golden horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'golden pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'rail': 'A rail can be crafted by placing a stick in the very middle square and iron ingots vertically in both the first and last column in a crafting table.', - 'wheat seeds': 'Wheat seeds are obtained by harvesting wheat.', - 'birch fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'purple stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'golden chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'leather boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'diamond shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'leather leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sand': 'Red sand can be found in Mesa biomes.', - 'vines': 'Vines can only be harvested with shears. Vines spawn naturally in jungle trees or in swamplands.', - 'glass bottle': 'A glass bottle is crafted by creating a V shape with three glass blocks in a crafting table.', - 'red stone ore': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'emerald block': 'Emerald blocks can be crafted by placing nine emeralds in a three by three grid in a crafting table.', - 'granite': 'Granite can be mined with a pick ax or crafted by placing Diorite and a nether quartz next to each other in a crafting table.', - 'brown wool': 'Brown wool can be crafted by placing brown dye next to any color wool in a crafting window.', - 'golden apple': 'A golden apple can be crafted by placing an apple in the very center square and eight gold ingots surrounding it.', - 'birch leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'white wool': 'White wool can be crated by placing four string in a two by two grid in a crafting window. It can also be obtained by placing bone meal next to any color wool in a crafting window', - 'purple carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'hardened clay': 'Hardened clay can be crafted by smelting a clay block in a furnace.', - 'zombie mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'iron trapdoor': 'An iron trapdoor can be crafted by placing iron ingots in a two by two grid in a crafting window.', - 'flower pot': 'A flower pot is crafted by placing three bricks in a V shape in a crafting table.', - 'iron ore': 'Iron ore can be obtained by breaking iron ore blocks with a stone pick ax or better', - 'jungle wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'jungle door': 'A Jungle Door can be crafted by placing six Jungle Planks down the first two columns.', - 'golden ax': 'All types of axes can be crafted by placing three of the desired materials in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'packed ice': 'Packed ice can be found in the rare ice plains spikes biome and can only be obtained with a silk touch tool.', - 'bricks': 'Bricks can be crafted by smelting clay in a furnace.', - 'light blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'dead shrub': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'dropper': 'A dropper can be crafted by placing red stone in the middle bottom square, and cobblestone in every other square but the center one.', - 'chest': 'A chest is crafted by placing wooden planks, in every square but the middle square, in a crafting table.', - 'raw chicken': 'Raw Chicken will drop from the death of a Chicken.', - 'raw salmon': 'Raw salmon is randomly obtained by fishing.', - 'tripwire hook': 'A tripwire hook can be crafted by placing an iron ingot on top of a stick on top of a wood plank in a crafting table.', - 'oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with command block': 'A mine cart with a command block can not be obtained without cheats.', - 'eye of ender': 'An eye of ender can be crafted by placing blaze power next to an ender pearl in a crafting window.', - 'block of coal': 'A block of coal can be crafted by placing coal in a three by three grid in a crafting window.', - 'nether star': 'A Nether Star can be obtained by defeating the Wither.', - 'gravel': 'Gravel can be obtained by breaking gravel blocks', - 'blue wool': 'Blue wool can be crafted by placing lapis lazuli next to any color wool in a crafting window.', - 'nether quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'rotten flesh': 'Rotten flesh can be randomly obtained by killing zombies.', - 'magenta carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'white stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'birch fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'carrots': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'purple dye': 'Purple dye can be crafted by placing lapis lazuli next to rose red in a crafting window.', - 'lapis lazuli block': 'A lapis lazuli block can be obtained by entirely filling a crafting table with lapis lazuli.', - 'obsidian': 'Obsidian can be mined with a diamond pick or created by placing water on top of lava. ', - 'mellohi disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music discs are found in eight percent of dungeon chests.', - 'gray wool': 'Gray wool can be crafted by placing gray dye next to any color wool in a crafting window.', - 'trapped chest': 'A trapped chest can be crafted by placing a tripwire hook next to a chest in a crafting window.', - 'light gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'red mushroom': 'Red mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'puffer fish': 'A puffer fish can be randomly obtained by fishing.', - 'emerald': 'Emeralds can be obtained by harvesting emerald ore.', - 'wooden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'golden helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'melon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest mine carts in abandoned mine shafts.', - 'clay block': 'Clay is commonly found at the bottoms of rivers and lakes in shallow, circular patches. Clay blocks can also be found commonly in swamps.', - 'anvil': 'An anvil can be crafted by placing three blocks of iron across the top row, an iron ingot in the very center square, and then three iron ingots across the bottom row in a crafting table.', - 'daylight sensor': 'A daylight sensor can be crafted by placing three glass across the top row, three nether quartz across the middle grow, anad three wooden slabs across the bottom row in a crafting table.', - 'lead': 'A lead can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'sandstone': 'Sandstone can be obtained in deserts or crafted by combining sand together in a two by two square.', - 'leather tunic': 'All chest pieces are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'black stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'lime stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mine cart with t.n.t': 'A Mine cart with T.N.T can be crafted by placing a T.N.T on top of a Mine cart in a crafting table.', - 'clock': 'A clock is crafted by placing red stone in the very center square and surrounding it with four gold ingots in a crafting table.', - 'black carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'cocoa': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'gold ingot': 'Gold ingots can be obtained by smelting gold ore in a furnace.', - 'stone brick slab': 'A stone brick slab can be crafted by placing three stone bricks in a row in a crafting table.', - 'clown fish': 'A clown fish can be randomly obtained by fishing.', - 'pumpkin seeds': 'Pumpkin seeds can be crafted by placing a pumpkin in a crafting window.', - 'mossy stone brick': 'Mossy stone brick can be crafted by placing vines next to stone bricks in a crafting window. Mossy stone brick can also be found naturally in strongholds.', - 'cobweb': 'Cobwebs can be obtained by using shears or a sword that is enchanted with silk touch', - 'milk bucket': 'A milk bucket can be obtained by right clicking on a cow with an iron bucket.', - 'iron helmet': 'All helmets are crafted by placing the desired material, in all squares but the very center square, and the bottom row, in a crafting table.', - 'yellow stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond': 'Diamond can be obtained by breaking diamond ore with an iron pick ax or better.', - 'stone sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'cobblestone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'bed': 'A bed can be crafted by placing three wool across the top row and three wooden planks across the middle row in a crafting table.', - 'birch wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'quartz slab': 'A quartz slab can be crafted by placing three quartz blocks in a row in a crafting table.', - 'sponge': 'Sponges can be obtained by killing an elder guardian or randomly finding them in ocean monuments', - 'skeleton mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'bucket': 'A bucket can be crafted by placing three iron ingots in a V shape in a crafting table.', - 'diamond sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'golden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'spruce wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'iron bars': 'Iron bars can be crafted by placing six iron ingots across the bottom two rows in a crafting table. Iron bars can also be found naturally in strongholds.', - 'raw rabbit': 'Raw rabbit can be randomly obtained by killing a rabbit.', - 'yellow carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'carrot on a stick': 'A carrot on a stick can be crafted by placing a fishing pole in the middle left square and a carrot in the bottom middle square in a crafting window.', - 'raw pork chop': 'A raw pork chop can be obtained by killing a pig.', - 'furnace': 'A furnace can be crafted by placing cobblestone in every square but the middle square in a crafting table.', - 'nether brick fence': 'A nether brick fence can be crafted by placing six nether brick across the bottom two rows in a crafting table.', - 'fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'diamond horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red sandstone slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood plank': 'Birch wood planks can be obtained by placing birch wood in a crafting table.', - 'bedrock': 'Bedrock can not be obtained by a player without cheats. It is the bottom most block in the game.', - 'saddle': 'Saddles can not be crafted and can only be obtained by finding them in chests inside dungeons, abandoned mine shafts, nether fortresses, desert temples, or jungle temples.', - 'light gray dye': 'Light gray dye can be crafted by placing two bone meal in a vertical row next to an ink sac in a crafting window.', - 'jungle leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'blocks disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'pumpkin': 'Pumpkins can be rarely be found on grass in most biomes.', - 'baked potato': 'A baked potato can be obtained by smelting a potato in a furnace.', - 'leather': 'Leather can be randomly obtained by killing cows or horses.', - 'light gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'end stone': 'End stone can be found naturally in the end dimension.', - 'chainmail leggings': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'rabbit\'s foot': 'A rabbit\'s foot can be obtained rarely by killing a rabbit.', - 'glass': 'Glass can be obtained by smelting sand in a furnace.', - 'stone': 'Stone can be made by smelting cobblestone in a furnace.', - 'prismarine': 'Prismarine can be crafted by placing prismarine shards in a two by two grid in a crafting window.', - 'compass': 'A compass is crafted by placing red stone in the very center square, and surrounding it with four iron ingots, in a crafting table.', - 'green stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'gold leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'command block': 'Command blocks can not be obtained without cheats in minecraft.', - 'dispenser': 'A dispenser can be created by placing a bow in the very center square, red stone right beneath that, and cobblestone in every other square.', - 'poisonous potato': 'A poisonous potato will randomly be dropped when harvesting potatoes.', - 'apple': 'Apples randomly drop from oak and dark oak leaves. They can also be randomly found in chests in strongholds or villages.', - 'red flower': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'magenta dye': 'Magenta dye can be crafted by placing purple dye next to pink dye in a crafting window.', - 'brown carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'prismarine shard': 'Prismarine Shards can be obtained by defeating Guardians and Elder Guardians.', - 'red stone block': 'A red stone block can be crafted by placing nine red stone in a three by three grid in a crafting table.', - 'yellow stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'dandelion yellow': 'Dandelion yellow is the equivalent of yellow dye in minecraft. It can be crafted by placing a dandelion or a sunflower in a crafting window.', - 'acacia wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'sandstone slab': 'A sandstone slab can be crated by placing three sandstone blocks in a row in a crafting table.', - 'gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished granite': 'Polished Granite can be crafted by placing four granite in a two by two grid in a crafting table.', - 'mine cart': 'A mine cart is crafted by placing five iron ingots in a U shape in a crafting table.', - 'brown stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'cyan stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'book': 'A book is crafted by creating a two by two grid where the bottom right square is leather and all other squares are paper in a crafting window.', - 'mine cart with a chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'acacia sapling': 'Acacia saplings can be randomly obtained by breaking acacia leaves.', - 'paper': 'Paper is crafted by placing three sugar cane, across a row, in a crafting table.', - 'gold chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cyan stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mushroom stew': 'Mushroom stew is crafted by placing a red mushroom in the middle left square, a brown mushroom in the very center square, and a bowl in the bottom middle square in a crafting table.', - 'nether brick': 'Nether Brick can be mined with a pick ax, or crafted by placing four Nether Bricks in a two by two square in a crafting table.', - 'magma cream': 'Magma cream can be crafted by placing blaze powder next to a slime ball in a crafting window.', - 'snow': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'orange dye': 'Orange dye can be crafted by placing rose red next to dandelion yellow in a crafting window.', - 'potion': 'A potion is created by utilizing a brewing stand, cauldron, and water bottles.', - 'lime stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'white stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'boat': 'A boat can be obtained by making a U shape with five wooden planks.', - 'dark prismarine': 'Dark prismarine can be crafted by placing an ink sac in the very center square, and then eight placing prismarine shards around it.', - 'oak door': 'A Oak Door can be crafted by placing six Oak Planks down the first two columns.', - 'cocoa beans': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'red wool': 'Red wool can be crafted by placing rose red next to any color wool in a crafting window.', - 'cooked mutton': 'Cooked mutton can be obtained by cooking raw mutton in a furnace. Alternately, one to two pieces of Cooked Mutton are dropped when a sheep dies while on fire.', - 'dark oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'iron door': 'An Iron Door can be crafted by placing six Iron Ingots down the first two columns.', - 'painting': 'A painting is crafted by placing wool in the very center square and surrounding it with eight sticks.', - 'spruce leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'pink stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'acacia wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'dark oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'chiseled sandstone': 'Chiseled sandstone can be created by placing a sandstone slab on top of a sandstone slab, in a crafting window.', - 'oak wood plank': 'Oak wood planks can be obtained by placing oak wood in a crafting table.', - 'cooked salmon': 'Cooked salmon is obtained by cooking salmon in a furnace.', - 'iron shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'enchanting table': 'An enchanting table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'red stone repeater': 'A red stone repeater can be crafted by placing smooth stone in all three squares across the bottom row, red stone in the very middle square, and red stone torches on both sides of the red stone.', - 'far disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'green carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron ingot': 'Iron ingots can be obtained by smelting iron ore in a furnace.', - 'orange wool': 'Orange wool can be crafted by placing orange dye next to any color wool in a crafting window.', - 'jungle sapling': 'Jungle saplings can be randomly obtained by breaking jungle leaves.', - 'stone slab': 'A stone slab can be crafted by placing three stone blocks in a row in a crafting table.', - 'light blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'cyan dye': 'Cyan dye can be crafted by placing lapis lazuli next to cactus green in a crafting window.', - 'steak': 'Raw Beef can be cooked into Steak by smelting it in a furnace. Alternately, Steak has a chance of dropping when a Cow or Moo shroom dies while on fire.', - 'orange stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'spruce fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'coal': 'Coal can be obtained by breaking a coal ore block with a wooden pick ax or better.', - 'potatoes': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'light gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'egg': 'Eggs are randomly produced by chickens. Throwing an egg has a chance to create a new chicken.', - 'spruce wood plank': 'Spruce wood planks can be obtained by placing spruce wood in a crafting table.', - 'orange stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'acacia wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'light gray wool': 'Light gray wool can be crafted by placing light gray dye next to any color wool in a crafting window.', - 'hay bale': 'A hay bale can be crafted by placing wheat in a three by three grid in a crafting table.', - 'clay': 'Clay is obtained by breaking clay blocks with a non silk touch tool.', - 'bowl': 'A bowl can be crafted by placing three wooden planks in a v shape in a crafting table.', - 'leather helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'pink stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'diamond chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'yellow stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'snowman': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'diamond ore': 'Diamond ore can be found in the bottom sixteen layers on the map. One can break diamond ore with an iron pick ax or better. This will cause the diamond ore to break into a diamond. To obtain the ore, you will need to use a pick ax with the silk touch enchant.', - 'banner': 'A Banner can be crafted by placing six wool across the top two rows, then placing a stick on the bottom middle. The banner will take on the color of the wool you choose.', - 'stone ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'firework star': 'A firework star can be crafted by placing gunpower in the middle left square and any color dye in the center square in a crafting table. A firework star can also be crafted with optional ingredients such as diamonds, glow stone dust, or feathers, that are placed directly beneath the dye in a crafting table.', - 'nether wart': 'Nether warts can be naturally found in nether fortresses as a plant.', - 'red stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'quartz block': 'A quartz block can be crafted by placing four nether quartz in a two by two grid in a crafting table.', - 'poppy': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'acacia fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'cactus': 'Cactus can be found naturally in desert biomes. ', - 'spruce door': 'A Spruce Door can be crafted by placing six Spruce Planks down the first two columns.', - 'cat disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'flint and steel': 'Flint and steel can be crafted by placing an iron ingot to the left of flint in a crafting window.', - 'gold pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'slime ball': 'Slime balls are randomly dropped by killing slimes.', - 'cooked porkchop': 'A cooked porkchop can be obtained by cooking a raw porkchop in a furnace or by lighting a pig on fire.', - 'polished andesite': 'Polished Andesite can be crafted by placing four andesite in a two by two grid in a crafting table.', - 'prismarine bricks': 'Prismarine bricks can be crafted by placing prismarine shards in a three by three grid in a crafting table.', - 'wither': 'A wither can be created by placing three wither skulls on top of soul sand that is placed on the ground in a T shape.', - 'lime dye': 'Lime dye can be crafted by placing cactus green next to bone meal in a crafting window.', - 'blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'door': 'A door can be crafted by placing six Planks, down the first two columns, in a crafting table.', - 'tripwire': 'Tripwire is simply string next to a tripwire hook.', - 'enchantment table': 'An enchantment table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'cyan carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished diorite': 'Polished Diorite can be crafted by placing four diorite in a two by two grid in a crafting table.', - 'golden boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'iron block': 'An iron block can be crafted by placing iron ingots in a three by three grid in a crafting table.', - 'acacia leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'dark oak sapling': 'Dark oak saplings can be randomly obtained by breaking dark oak leaves', - 'diamond hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'dandelion': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'lapis lazuli': 'Can be obtained by breaking lapis lazuli ore with a stone pick ax or better', - 'sugar cane': 'Sugar cane can be found naturally near water,', - 'birch door': 'A Birch Door can be crafted by placing six Birch Planks down the first two columns.', - 'cactus green': 'Cactus green can be crafted by smelting a cactus in a furnace.', - 'gold block': 'A gold block can be crafted by placing gold ingots in a three by three grid in a crafting table.', - 'smooth sandstone': 'Smooth sandstone can be created by placing sandstone in a two by two grid in a crafting window', - 'magenta stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'note block': 'A note block is crafted by placing red stone in the very center square and wooden planks all around that in a crafting table', - 'snow block': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'diamond leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sandstone': 'Red sandstone can be crafted by placing four red sand in a two by two grid in a crafting window.', - 'orange stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'slime block': 'A slime block can be crafted by placing slime balls in a three by three grid in a crafting window.', - 'bookshelf': 'A bookshelf is crafted by placing books across the middle row and wooden planks across the top and bottom rows', - 'cake': 'Cake can be crafted by placing three buckets of milk across the top row, sugar in the left middle, and right middle squares, an egg in the very center square, and three wheat across the bottom squares in a crafting table.', - 'wooden button': 'A wooden button can be crafted by placing a single wooden plank in a crafting window.', - 'chiseled quartz block': 'A chiseled quartz block can be obtained by placing a quartz slab on top of a quartz slab in a crafting table.', - 'stone button': 'A stone button can be crafted by placing a single piece of smooth stone in a crafting window.', - 'glow stone dust': 'Glow stone dust is obtained by breaking glow stone blocks.', - 'lime stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cobblestone wall': 'A cobblestone wall is crafted by placing six cobblestone across the bottom two rows in a crafting table.', - 'name tag': 'Name Tags can only be obtained in three ways. The first way is by finding it in a Dungeon chest. The second way is by fishing. The last way Name Tags can be obtained is by trading with the Librarian Villagers for twenty to twenty two Emeralds.', - 'gunpowder': 'Gunpowder can be randomly obtained by killing creepers.', - 'blaze powder': 'Blaze powder can be obtained by placing a blaze row in a crafting window.', - 'brewing stand': 'A brewing stand can be crafted by placing a blaze rod in the center square, and three cobblestone across the bottom row in a crafting table.', - 'torch': 'A torch can be crafted by placing a piece of coal on top of a stick.', - 'yellow wool': 'Yellow wool can be crafted by placing dandelion yellow next to any color wool in a crafting window.', - 'watermelon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest minecarts in abandoned mine shafts.', - 'wait disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'glistering melon': 'A glistering melon can be crafted by placing a melon in the very center square and surrounding it with eight gold nuggets in a crafting table.', - 'netherrack': 'Netherrack can be found commonly throughout the Nether dimension.', - 'leather chest plate': 'All chest places are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'wooden slab': 'A wooden slab can be crafted by placing three wooden planks in a row in a crafting table.', - 'nether brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ice': 'Ice can be found naturally in snow biomes. If broken, or placed near a heat source, ice will turn into water. To obtain an ice block, one would need to mine it with a silk touch pick ax.', - 'large fern': 'Large ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'nether brick slab': 'A nether brick slab can be crafted by placing three nether brick in a row in a crafting table.', - 'spruce wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'iron hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'fern': 'Ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'sea lantern': 'A sea lantern can be crafted by placing prismarine shards in the four corners of a crafting table, and then placing prismarine crystals in every other square.', - 'cookie': 'A cookie can be crafted by placing wheat, horizontally, on both sides of cocoa beans in a crafting table.', - 'melon seeds': 'Melon seeds can be crafted by placing a slice of melon in a crafting window.', - 'gold nugget': 'A gold nugget can be crafted by placing a single gold ingot into a crafting window. They can also be randomly obtained by killing a zombie pig men.', - 'red stone ore block': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'diamond helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'spruce fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'golden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'acacia wood plank': 'Acacia wood planks can be obtained by placing acacia wood in a crafting table', - 'diamond pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'lapis lazuli ore': 'Lapis Lazuli Ore can be only be obtained by using a pick ax with the silk touch enchant.', - 'raw mutton': 'Raw mutton can be obtained by killing a sheep.', - 'quartz stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'brick block': 'A brick block can be crafted by placing clay bricks in a two by two grid in a crafting window.', - 'cobblestone slab': 'A cobblestone slab can be crafted by placing three cobblestone blocks in a row in a crafting table.', - 'emerald ore': 'Emerald ore can only be found in extreme hills biomes between layers four and thirty-two. It can be mined with an iron pick ax or better to obtain an emerald. To obtain the ore itself, you will need a silk touch pick ax.', - 'yellow flower': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'jack o\'lantern': 'A jack o\'lantern can be crafted by placing a pumpkin on top of a torch in a crafting table.', - 'red stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'iron leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'pink stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'black dye': 'An ink sack is used as black dye in mine craft.', - 'wooden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'purple stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'detector rail': 'A detector rail can be crafted by placing a stone pressure plate in the very center square, red stone in the bottom middle square, and iron ingots in the far left and far right columns', - 'cyan wool': 'Cyan wool can be crafted by placing cyan dye next to any color wool in a crafting window.', - 'iron chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cobblestone': 'Cobblestone can be obtained by breaking stone with a pick ax.', - 'dark oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'creeper mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'carrot': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'rabbit hide': 'Rabbit hide can be randomly obtained by killing a rabbit.', - 'grass': 'When harvested with a regular shovel, grass turns into dirt. In order to obtain a grass block you will need to have a shovel with the silk touch enchant.', - 'strad disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'birch sapling': 'Birch saplings can be randomly obtained by breaking birch leaves.', - 'mossy stone': 'Mossy stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'pink dye': 'Pink dye can be crafted by placing bone meal next to rose red in a crafting window.', - 'red stone torch': 'A red stone torch is crafted by placing red stone on top of a torch in a crafting window.', - 'green stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'tall grass': 'Tall grass, which is called grass in a players inventory, spawns on grass blacks in certain biomes. Bonemeal can be used on a grass block to grow tall grass and occasionally flowers.', - 'black wool': 'Black wool can be crafted by placing an ink sac next to any color wool in a crafting window.', - 'wheat crops': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'ender pearl': 'Ender pearls can be randomly obtained by killing ender men.', - 'moss stone': 'Moss stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'fishing rod': 'A fishing rod is crafted by placing three sticks in a diagonal line, and then two string beneath the top right stick in a crafting window.', - 'bone meal': 'Bone meal can be crafted by placing a bone into a crafting window.', - 'quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'dark oak wood plank': 'Dark oak wood planks can be obtained by placing dark oak wood in a crafting table.', - 'powered rail': 'A powered rail can be crafted by placing a stick in the very center square, red stone in the bottom middle square, and gold ingots in the far left and far right columns', - 'beacon': 'A beacon can be obtained by placing a nether star in the very center square, three obsidian across the bottom row, and five glass in the remaining squares in a crafting table.', - 'blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'dark oak door': 'A Dark Oak Door can be crafted by placing six Dark Oak Planks down the first two columns.', - 'iron golem': 'An iron golem can be created by similarly to a snow golem. Place a pumpkin head on top of two iron blocks. Then place two more iron blocks on either side of the very center iron block.', - 'spruce wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'pink wool': 'Pink wool can be crafted by placing pink dye next to any color wool in a crafting window.', - 'fire charge': 'A fire charge can be crafted by placing blaze powder in the middle left square, coal in the very center square, and gunpowder in the bottom middle square in a crafting table.', - 'acacia door': 'An Acacia Door can be crafted by placing six Acacia Planks down the first two columns.', - 'iron pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chirp disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'arrow': 'An arrow can be crafted by placing flint in the top middle square, a stick in the very center square, and a feather in the bottom middle square in a crafting table.', - 'wooden ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'glass pane': 'A glass pane can be crafted by placing six glass blocks across the bottom two rows in a crafting table.', - 'gold helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'ender chest': 'An ender chest can be crafted by placing an eye of ender in the center square, and then surrounding that with eight obsidian blocks in a crafting table.', - 'light blue wool': 'Light blue wool can be crafted by placing light blue dye next to any color wool in a crafting window.', - 'string': 'String can be randomly obtained by killing spiders or by breaking cobwebs.', - 'red sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'purple wool': 'Purple wool can be crafted by placing purple dye next to any color wool in a crafting window.', - 'cyan stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'black stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'enchanted book': 'Enchanted books can be found in chests located in dungeons, strongholds, desert temples, jungle temples, and mine shafts.', - 'button': 'A button can be crafted by placing either a single piece of smooth stone or a single wooden plank in a crafting window.', - 'lime wool': 'Lime wool can be crafted by placing lime dye next to any color wool in a crafting window.', - 'coarse dirt': 'Coarse dirt can be obtained by breaking dirt in the Mega Taiga, Mesa, or Savanna biomes.', - 'ghast tear': 'Ghast tears can be rarely obtained by killing ghasts.', - 'mine cart with a furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'wheat': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'soul sand': 'Soul sand can be found commonly throughout the Nether dimension.', - 'brown mushroom': 'Brown mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'chainmail helmet': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'written book': 'A written book is created after a book and quill is signed.', - 'spruce sapling': 'Spruce saplings can be randomly obtained by breaking spruce leaves.', - 'oak sapling': 'Oak saplings can be randomly obtained by breaking oak leaves.', - 'inverted daylight sensor': 'An inverted daylight sensor can be created by right clicking on a daylight sensor.', - 'sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'red stone lamp': 'A red stone lamp can be crafted by placing glow stone in the very center square, and surrounding it with four red stone in a crafting table.', - 'crafting table': 'A crafting table is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'glow stone': 'Glow stone can be found on the ceiling in the Nether dimension.', - 'wooden pressure plate': 'A wooden pressure plate can be created by placing two wooden planks, horizontally, next to each other in a crafting window.', - 'charcoal': 'Charcoal can be obtained by burning wood blocks in a furnace.', - 'chainmail boots': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'ladder': 'A ladder is crafted by placing sticks in every square but the top middle and bottom middle square.', - 'mossy cobblestone': 'Mossy cobblestone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'golden pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'seeds': 'Wheat seeds can be randomly found by breaking tall grass.', - 'acacia fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'birch wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ward disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'music disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'enchanted golden apple': 'An enchanted golden apple is crafted by placing an apple in the very center square and surrounding it with eight gold blocks.', - 'white carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'diamonds pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chiseled red sandstone': 'Chiseled red sandstone can be crafted by placing a red sandstone slab on top of a red sandstone slab in a crafting window.', - 'stone brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'pressure plate': 'A pressure plate can be created by placing either two smooth stone or two wooden planks next to each other, horizontally, in a crafting window.', - 'jungle wood plank': 'Jungle wood planks can be obtained by placing jungle wood in a crafting table', - 'green wool': 'Green wool can be crafted by placing cactus green next to any color wool in a crafting window.', - 'sugar canes': 'Sugar canes occur naturally near water.', - 'bow': 'A bow can be crafted by placing three string in the rightmost column and then placing tree sticks in a less than sign pattern next to the string in a crafting table.', - 'lime carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'flint': 'Flint is randomly dropped while breaking gravel.', - 'black stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - }, - 'RECIPE_EN_US': { - 'snow golem': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'pillar quartz block': 'A pillar of quartz can be obtained by placing a block of quartz on top of a block of quartz in mine craft.', - 'firework rocket': 'A firework rocket can be crafted by placing a firework star in the left middle square, a piece of paper in the center square, and gunpowder in the right middle square in a crafting table. Similar to a firework star, a firework rocket can have more gunpowder added in the bottom row to increase the duration of a rocket.', - 'rabbit stew': 'Rabbit stew can be crafted by placing cooked rabbit in the top middle square, a carrot in the middle left square, a baked potato in the center square, any type of mushroom in the middle right square, and a bowl in the bottom middle square.', - 'cauldron': 'A cauldron can be created by placing iron ingots in all squares but the top middle and very center squares in a crafting table.', - 'stone shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'red carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'book and quill': 'A book and quill can be crafted by placing a book in the middle left square, an ink sac in the very center square, and a feather in the bottom middle square in a crafting table.', - 'item frame': 'An item frame can be crafted by placing leather in the very center square, and eight sticks surrounding it.', - 'map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'sticky piston': 'A sticky piston can be crafted by placing a slime ball on top of a piston in a crafting window', - 'bread': 'Bread can be crafted by placing three wheat across a row in a crafting table.', - 'wooden pick ax': 'All types of pick axs can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'shears': 'Shears can be crafted by placing two Iron Ingots diagonal from each other.', - 'raw beef': 'Raw Beef will drop from the death of a Cow or Moo shrooms.', - 'smooth red sandstone': 'Smooth red sandstone can be crafted by placing four red sandstone in a two by two grid in a crafting window.', - 'prismarine crystals': 'Prismarine Crystals can be obtained by defeating Guardians and Elder Guardians.', - 'oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'wooden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'jungle fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'activator rail': 'An activator rail can be crafted by placing a red stone torch in the very center square, sticks above and beneath it, and then six iron ingots in the remaining squares in a crafting table.', - 'farmland': 'Farmland can be created by plowing the land with a hoe.', - 'gold ore': 'Gold ore can be obtained by breaking gold ore blocks with an iron pick ax or better', - 'andesite': 'Andesite can be mined with a pick ax or crafted by placing diorite next to cobblestone in a crafting table.', - 'rose red': 'Rose red can be crafted by placing a poppy into a crafting table.', - 'iron axe': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'light blue dye': 'Light blue dye can be crafted by placing lapis lazuli next to bone meal in a crafting window.', - 'gray dye': 'Gray dye can be crafted by placing bonemeal next to an ink sac in a crafting window', - 'blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'golden leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'dark oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'wither mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'spider eye': 'A spider eye is randomly dropped by killing spiders or witches.', - 'magenta stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'brown stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'pumpkin pie': 'A pumpkin pie can be crafted by placing a pumpkin in the left middle square, sugar in the very center square, and an egg in the bottom middle square in a crafting table.', - 'snowball': 'A snowball can be obtained by breaking snow with a shovel.', - 'juke box': 'A juke box is crafted by placing a diamond in the very center square and wood planks all around that in a crafting table', - 'sand': 'Sand can be obtained by breaking sand blocks.', - 'dead bush': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'brick slab': 'A brick slab can be crafted by placing three brick blocks in a row in a crafting table.', - 'lily pad': 'Lily pads can be found naturally on water in swamplands or underground lakes.', - 'leather pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'mossy cobblestone wall': 'A mossy cobblestone wall is crafted by placing six mossy cobblestone across the bottom two rows in a crafting table.', - 'eleven disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'purple stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'magenta stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'mall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'jungle wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diamond ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'empty map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'stone pressure plate': 'A stone pressure plate can be crafted by placing two smooth stone, next to each other, horizontally, in a crafting window.', - 'trapdoor': 'Trapdoors can be crafted with either wooden planks or iron ingots. To craft a wooden trapdoor, place wooden planks in all spaces in the bottom two rows. To craft an iron trapdoor, place iron ingots in a two by two grid in a crafting table.', - 'gold boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'red stone wire': 'Redstone wire is simply red stone placed on the floor.', - 'piston': 'A piston can be crafted by placing an iron ingot in the center square, red stone in the bottom middle square, wooden planks across the top row, and cobblestone in the remaining squares.', - 'white stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'sugar': 'Sugar can be obtained by placing sugar cane in a crafting window.', - 'chain mail chest plate': 'Chain mail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'feather': 'Feathers can be randomly obtained by killing chickens.', - 'light blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'stone pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'pink carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'monster spawner': 'Monster spawners can not be obtained without cheats in mine craft.', - 'golden carrot': 'A golden carrot can be crafted by placing a carrot in the very middle square and eight gold nuggets surrounding that.', - 'stick': 'A stick can be crafted by placing a wooden plank on top of a wooden plank in a crafting window.', - 'diamond block': 'A diamond block can be crafted by placing diamonds in every square in a crafting table.', - 'green stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cooked chicken': 'Raw Chicken can be cooked by smelting it in a furnace. Alternately, Cooked Chicken has a chance of dropping when a Chicken dies while on fire.', - 'thirteen disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'wooden trapdoor': 'A wooden trapdoor can be crafted by placing wooden planks in all spaces in the bottom two rows in a crafting table.', - 'oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'crafting bench': 'A crafting bench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'nether quartz ore': 'Nether quartz ore can be randomly found in the nether. To obtain the ore instead of nether quartz, you will need to use a silk touch pick ax.', - 'golden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stone hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'coal ore': 'Coal ore can be obtained by breaking a coal ore block with a pick ax that is enchanted with silk touch', - 'dark oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 't.n.t.': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'brick': 'A brick can be crafted by smelting clay in a furnace.', - 'potato': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'orange carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'ink sack': 'An ink sack can be obtained by killing a squid.', - 'red stone': 'Redstone can be obtained by breaking red stone ore with an iron pick ax or better.', - 'dark oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diorite': 'Diorite can be mined with a pick ax or crafted by combining cobblestone and nether quartz in a two by two grid in a crafting table.', - 'workbench': 'A workbench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'jungle fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'magenta wool': 'Magenta wool can be crafted by placing magenta dye next to any color wool in a crafting window.', - 'dirt': 'Dirt can be obtained by breaking grass or dirt with a shovel.', - 'armor stand': 'An Armor Stand can be crafted with six sticks and one stone slab. Take three sticks and place it across the first row. Take the remaining three sticks and place one each in the bottom left, bottom right, and center middle. Place the stone slab in the bottom middle.', - 'cooked fish': 'Cooked fish is obtained by cooking fish in a furnace.', - 'lever': 'A lever can be crafted by placing a stick on top of cobblestone in a crafting window.', - 'leash': 'A leash can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'cooked rabbit': 'Cooked rabbit can be obtained by cooking raw rabbit in a furnace. Alternately, Cooked Rabbit has a chance of dropping when a Rabbit dies while on fire.', - 'jungle wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with hopper': 'A Mine cart With a Hopper can be crafted by placing a Hopper on top of a Mine cart in a crafting table.', - 'fermented spider eye': 'Fermented spider eye can be obtained by placing a brown mushroom in the middle left square, sugar in the very center square, and a spider eye in the bottom middle square in a crafting table.', - 'raw fish': 'Raw fish is randomly obtained by fishing.', - 'brown stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'sign': 'A sign is crafted by placing wooden planks in the top two rows and a stick in the bottom middle square.', - 't.n.t': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'hopper': 'A hopper can be crafted by placing a chest in the very center square, and then iron ingots in every square but the top middle, bottom left, and bottom right squares in a crafting grid.', - 'blaze rod': 'Blaze rods can be randomly obtained by killing blazes.', - 'red stone comparator': 'A red stone comparator can be crafted by placing three smooth stone across the bottom row, a nether quartz in the center square, and three red stone torches surrounding the nether quartz in a crafting table.', - 'bone': 'Bones can be obtained by killing skeletons.', - 'golden horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'golden pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'rail': 'A rail can be crafted by placing a stick in the very middle square and iron ingots vertically in both the first and last column in a crafting table.', - 'wheat seeds': 'Wheat seeds are obtained by harvesting wheat.', - 'birch fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'purple stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'golden chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'leather boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'diamond shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'leather leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sand': 'Red sand can be found in Mesa biomes.', - 'vines': 'Vines can only be harvested with shears. Vines spawn naturally in jungle trees or in swamplands.', - 'glass bottle': 'A glass bottle is crafted by creating a V shape with three glass blocks in a crafting table.', - 'red stone ore': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'emerald block': 'Emerald blocks can be crafted by placing nine emeralds in a three by three grid in a crafting table.', - 'granite': 'Granite can be mined with a pick ax or crafted by placing Diorite and a nether quartz next to each other in a crafting table.', - 'brown wool': 'Brown wool can be crafted by placing brown dye next to any color wool in a crafting window.', - 'golden apple': 'A golden apple can be crafted by placing an apple in the very center square and eight gold ingots surrounding it.', - 'birch leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'white wool': 'White wool can be crated by placing four string in a two by two grid in a crafting window. It can also be obtained by placing bone meal next to any color wool in a crafting window', - 'purple carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'hardened clay': 'Hardened clay can be crafted by smelting a clay block in a furnace.', - 'zombie mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'iron trapdoor': 'An iron trapdoor can be crafted by placing iron ingots in a two by two grid in a crafting window.', - 'flower pot': 'A flower pot is crafted by placing three bricks in a V shape in a crafting table.', - 'iron ore': 'Iron ore can be obtained by breaking iron ore blocks with a stone pick ax or better', - 'jungle wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'jungle door': 'A Jungle Door can be crafted by placing six Jungle Planks down the first two columns.', - 'golden ax': 'All types of axes can be crafted by placing three of the desired materials in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'packed ice': 'Packed ice can be found in the rare ice plains spikes biome and can only be obtained with a silk touch tool.', - 'bricks': 'Bricks can be crafted by smelting clay in a furnace.', - 'light blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'dead shrub': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'dropper': 'A dropper can be crafted by placing red stone in the middle bottom square, and cobblestone in every other square but the center one.', - 'chest': 'A chest is crafted by placing wooden planks, in every square but the middle square, in a crafting table.', - 'raw chicken': 'Raw Chicken will drop from the death of a Chicken.', - 'raw salmon': 'Raw salmon is randomly obtained by fishing.', - 'tripwire hook': 'A tripwire hook can be crafted by placing an iron ingot on top of a stick on top of a wood plank in a crafting table.', - 'oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with command block': 'A mine cart with a command block can not be obtained without cheats.', - 'eye of ender': 'An eye of ender can be crafted by placing blaze power next to an ender pearl in a crafting window.', - 'block of coal': 'A block of coal can be crafted by placing coal in a three by three grid in a crafting window.', - 'nether star': 'A Nether Star can be obtained by defeating the Wither.', - 'gravel': 'Gravel can be obtained by breaking gravel blocks', - 'blue wool': 'Blue wool can be crafted by placing lapis lazuli next to any color wool in a crafting window.', - 'nether quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'rotten flesh': 'Rotten flesh can be randomly obtained by killing zombies.', - 'magenta carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'white stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'birch fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'carrots': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'purple dye': 'Purple dye can be crafted by placing lapis lazuli next to rose red in a crafting window.', - 'lapis lazuli block': 'A lapis lazuli block can be obtained by entirely filling a crafting table with lapis lazuli.', - 'obsidian': 'Obsidian can be mined with a diamond pick or created by placing water on top of lava. ', - 'mellohi disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music discs are found in eight percent of dungeon chests.', - 'gray wool': 'Gray wool can be crafted by placing gray dye next to any color wool in a crafting window.', - 'trapped chest': 'A trapped chest can be crafted by placing a tripwire hook next to a chest in a crafting window.', - 'light gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'red mushroom': 'Red mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'puffer fish': 'A puffer fish can be randomly obtained by fishing.', - 'emerald': 'Emeralds can be obtained by harvesting emerald ore.', - 'wooden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'golden helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'melon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest mine carts in abandoned mine shafts.', - 'clay block': 'Clay is commonly found at the bottoms of rivers and lakes in shallow, circular patches. Clay blocks can also be found commonly in swamps.', - 'anvil': 'An anvil can be crafted by placing three blocks of iron across the top row, an iron ingot in the very center square, and then three iron ingots across the bottom row in a crafting table.', - 'daylight sensor': 'A daylight sensor can be crafted by placing three glass across the top row, three nether quartz across the middle grow, anad three wooden slabs across the bottom row in a crafting table.', - 'lead': 'A lead can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'sandstone': 'Sandstone can be obtained in deserts or crafted by combining sand together in a two by two square.', - 'leather tunic': 'All chest pieces are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'black stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'lime stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mine cart with t.n.t': 'A Mine cart with T.N.T can be crafted by placing a T.N.T on top of a Mine cart in a crafting table.', - 'clock': 'A clock is crafted by placing red stone in the very center square and surrounding it with four gold ingots in a crafting table.', - 'black carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'cocoa': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'gold ingot': 'Gold ingots can be obtained by smelting gold ore in a furnace.', - 'stone brick slab': 'A stone brick slab can be crafted by placing three stone bricks in a row in a crafting table.', - 'clown fish': 'A clown fish can be randomly obtained by fishing.', - 'pumpkin seeds': 'Pumpkin seeds can be crafted by placing a pumpkin in a crafting window.', - 'mossy stone brick': 'Mossy stone brick can be crafted by placing vines next to stone bricks in a crafting window. Mossy stone brick can also be found naturally in strongholds.', - 'cobweb': 'Cobwebs can be obtained by using shears or a sword that is enchanted with silk touch', - 'milk bucket': 'A milk bucket can be obtained by right clicking on a cow with an iron bucket.', - 'iron helmet': 'All helmets are crafted by placing the desired material, in all squares but the very center square, and the bottom row, in a crafting table.', - 'yellow stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond': 'Diamond can be obtained by breaking diamond ore with an iron pick ax or better.', - 'stone sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'cobblestone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'bed': 'A bed can be crafted by placing three wool across the top row and three wooden planks across the middle row in a crafting table.', - 'birch wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'quartz slab': 'A quartz slab can be crafted by placing three quartz blocks in a row in a crafting table.', - 'sponge': 'Sponges can be obtained by killing an elder guardian or randomly finding them in ocean monuments', - 'skeleton mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'bucket': 'A bucket can be crafted by placing three iron ingots in a V shape in a crafting table.', - 'diamond sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'golden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'spruce wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'iron bars': 'Iron bars can be crafted by placing six iron ingots across the bottom two rows in a crafting table. Iron bars can also be found naturally in strongholds.', - 'raw rabbit': 'Raw rabbit can be randomly obtained by killing a rabbit.', - 'yellow carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'carrot on a stick': 'A carrot on a stick can be crafted by placing a fishing pole in the middle left square and a carrot in the bottom middle square in a crafting window.', - 'raw pork chop': 'A raw pork chop can be obtained by killing a pig.', - 'furnace': 'A furnace can be crafted by placing cobblestone in every square but the middle square in a crafting table.', - 'nether brick fence': 'A nether brick fence can be crafted by placing six nether brick across the bottom two rows in a crafting table.', - 'fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'diamond horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red sandstone slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood plank': 'Birch wood planks can be obtained by placing birch wood in a crafting table.', - 'bedrock': 'Bedrock can not be obtained by a player without cheats. It is the bottom most block in the game.', - 'saddle': 'Saddles can not be crafted and can only be obtained by finding them in chests inside dungeons, abandoned mine shafts, nether fortresses, desert temples, or jungle temples.', - 'light gray dye': 'Light gray dye can be crafted by placing two bone meal in a vertical row next to an ink sac in a crafting window.', - 'jungle leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'blocks disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'pumpkin': 'Pumpkins can be rarely be found on grass in most biomes.', - 'baked potato': 'A baked potato can be obtained by smelting a potato in a furnace.', - 'leather': 'Leather can be randomly obtained by killing cows or horses.', - 'light gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'end stone': 'End stone can be found naturally in the end dimension.', - 'chainmail leggings': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'rabbit\'s foot': 'A rabbit\'s foot can be obtained rarely by killing a rabbit.', - 'glass': 'Glass can be obtained by smelting sand in a furnace.', - 'stone': 'Stone can be made by smelting cobblestone in a furnace.', - 'prismarine': 'Prismarine can be crafted by placing prismarine shards in a two by two grid in a crafting window.', - 'compass': 'A compass is crafted by placing red stone in the very center square, and surrounding it with four iron ingots, in a crafting table.', - 'green stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'gold leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'command block': 'Command blocks can not be obtained without cheats in minecraft.', - 'dispenser': 'A dispenser can be created by placing a bow in the very center square, red stone right beneath that, and cobblestone in every other square.', - 'poisonous potato': 'A poisonous potato will randomly be dropped when harvesting potatoes.', - 'apple': 'Apples randomly drop from oak and dark oak leaves. They can also be randomly found in chests in strongholds or villages.', - 'red flower': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'magenta dye': 'Magenta dye can be crafted by placing purple dye next to pink dye in a crafting window.', - 'brown carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'prismarine shard': 'Prismarine Shards can be obtained by defeating Guardians and Elder Guardians.', - 'red stone block': 'A red stone block can be crafted by placing nine red stone in a three by three grid in a crafting table.', - 'yellow stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'dandelion yellow': 'Dandelion yellow is the equivalent of yellow dye in minecraft. It can be crafted by placing a dandelion or a sunflower in a crafting window.', - 'acacia wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'sandstone slab': 'A sandstone slab can be crated by placing three sandstone blocks in a row in a crafting table.', - 'gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished granite': 'Polished Granite can be crafted by placing four granite in a two by two grid in a crafting table.', - 'mine cart': 'A mine cart is crafted by placing five iron ingots in a U shape in a crafting table.', - 'brown stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'cyan stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'book': 'A book is crafted by creating a two by two grid where the bottom right square is leather and all other squares are paper in a crafting window.', - 'mine cart with a chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'acacia sapling': 'Acacia saplings can be randomly obtained by breaking acacia leaves.', - 'paper': 'Paper is crafted by placing three sugar cane, across a row, in a crafting table.', - 'gold chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cyan stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mushroom stew': 'Mushroom stew is crafted by placing a red mushroom in the middle left square, a brown mushroom in the very center square, and a bowl in the bottom middle square in a crafting table.', - 'nether brick': 'Nether Brick can be mined with a pick ax, or crafted by placing four Nether Bricks in a two by two square in a crafting table.', - 'magma cream': 'Magma cream can be crafted by placing blaze powder next to a slime ball in a crafting window.', - 'snow': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'orange dye': 'Orange dye can be crafted by placing rose red next to dandelion yellow in a crafting window.', - 'potion': 'A potion is created by utilizing a brewing stand, cauldron, and water bottles.', - 'lime stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'white stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'boat': 'A boat can be obtained by making a U shape with five wooden planks.', - 'dark prismarine': 'Dark prismarine can be crafted by placing an ink sac in the very center square, and then eight placing prismarine shards around it.', - 'oak door': 'A Oak Door can be crafted by placing six Oak Planks down the first two columns.', - 'cocoa beans': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'red wool': 'Red wool can be crafted by placing rose red next to any color wool in a crafting window.', - 'cooked mutton': 'Cooked mutton can be obtained by cooking raw mutton in a furnace. Alternately, one to two pieces of Cooked Mutton are dropped when a sheep dies while on fire.', - 'dark oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'iron door': 'An Iron Door can be crafted by placing six Iron Ingots down the first two columns.', - 'painting': 'A painting is crafted by placing wool in the very center square and surrounding it with eight sticks.', - 'spruce leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'pink stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'acacia wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'dark oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'chiseled sandstone': 'Chiseled sandstone can be created by placing a sandstone slab on top of a sandstone slab, in a crafting window.', - 'oak wood plank': 'Oak wood planks can be obtained by placing oak wood in a crafting table.', - 'cooked salmon': 'Cooked salmon is obtained by cooking salmon in a furnace.', - 'iron shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'enchanting table': 'An enchanting table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'red stone repeater': 'A red stone repeater can be crafted by placing smooth stone in all three squares across the bottom row, red stone in the very middle square, and red stone torches on both sides of the red stone.', - 'far disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'green carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron ingot': 'Iron ingots can be obtained by smelting iron ore in a furnace.', - 'orange wool': 'Orange wool can be crafted by placing orange dye next to any color wool in a crafting window.', - 'jungle sapling': 'Jungle saplings can be randomly obtained by breaking jungle leaves.', - 'stone slab': 'A stone slab can be crafted by placing three stone blocks in a row in a crafting table.', - 'light blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'cyan dye': 'Cyan dye can be crafted by placing lapis lazuli next to cactus green in a crafting window.', - 'steak': 'Raw Beef can be cooked into Steak by smelting it in a furnace. Alternately, Steak has a chance of dropping when a Cow or Moo shroom dies while on fire.', - 'orange stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'spruce fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'coal': 'Coal can be obtained by breaking a coal ore block with a wooden pick ax or better.', - 'potatoes': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'light gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'egg': 'Eggs are randomly produced by chickens. Throwing an egg has a chance to create a new chicken.', - 'spruce wood plank': 'Spruce wood planks can be obtained by placing spruce wood in a crafting table.', - 'orange stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'acacia wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'light gray wool': 'Light gray wool can be crafted by placing light gray dye next to any color wool in a crafting window.', - 'hay bale': 'A hay bale can be crafted by placing wheat in a three by three grid in a crafting table.', - 'clay': 'Clay is obtained by breaking clay blocks with a non silk touch tool.', - 'bowl': 'A bowl can be crafted by placing three wooden planks in a v shape in a crafting table.', - 'leather helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'pink stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'diamond chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'yellow stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'snowman': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'diamond ore': 'Diamond ore can be found in the bottom sixteen layers on the map. One can break diamond ore with an iron pick ax or better. This will cause the diamond ore to break into a diamond. To obtain the ore, you will need to use a pick ax with the silk touch enchant.', - 'banner': 'A Banner can be crafted by placing six wool across the top two rows, then placing a stick on the bottom middle. The banner will take on the color of the wool you choose.', - 'stone ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'firework star': 'A firework star can be crafted by placing gunpower in the middle left square and any color dye in the center square in a crafting table. A firework star can also be crafted with optional ingredients such as diamonds, glow stone dust, or feathers, that are placed directly beneath the dye in a crafting table.', - 'nether wart': 'Nether warts can be naturally found in nether fortresses as a plant.', - 'red stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'quartz block': 'A quartz block can be crafted by placing four nether quartz in a two by two grid in a crafting table.', - 'poppy': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'acacia fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'cactus': 'Cactus can be found naturally in desert biomes. ', - 'spruce door': 'A Spruce Door can be crafted by placing six Spruce Planks down the first two columns.', - 'cat disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'flint and steel': 'Flint and steel can be crafted by placing an iron ingot to the left of flint in a crafting window.', - 'gold pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'slime ball': 'Slime balls are randomly dropped by killing slimes.', - 'cooked porkchop': 'A cooked porkchop can be obtained by cooking a raw porkchop in a furnace or by lighting a pig on fire.', - 'polished andesite': 'Polished Andesite can be crafted by placing four andesite in a two by two grid in a crafting table.', - 'prismarine bricks': 'Prismarine bricks can be crafted by placing prismarine shards in a three by three grid in a crafting table.', - 'wither': 'A wither can be created by placing three wither skulls on top of soul sand that is placed on the ground in a T shape.', - 'lime dye': 'Lime dye can be crafted by placing cactus green next to bone meal in a crafting window.', - 'blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'door': 'A door can be crafted by placing six Planks, down the first two columns, in a crafting table.', - 'tripwire': 'Tripwire is simply string next to a tripwire hook.', - 'enchantment table': 'An enchantment table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'cyan carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished diorite': 'Polished Diorite can be crafted by placing four diorite in a two by two grid in a crafting table.', - 'golden boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'iron block': 'An iron block can be crafted by placing iron ingots in a three by three grid in a crafting table.', - 'acacia leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'dark oak sapling': 'Dark oak saplings can be randomly obtained by breaking dark oak leaves', - 'diamond hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'dandelion': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'lapis lazuli': 'Can be obtained by breaking lapis lazuli ore with a stone pick ax or better', - 'sugar cane': 'Sugar cane can be found naturally near water,', - 'birch door': 'A Birch Door can be crafted by placing six Birch Planks down the first two columns.', - 'cactus green': 'Cactus green can be crafted by smelting a cactus in a furnace.', - 'gold block': 'A gold block can be crafted by placing gold ingots in a three by three grid in a crafting table.', - 'smooth sandstone': 'Smooth sandstone can be created by placing sandstone in a two by two grid in a crafting window', - 'magenta stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'note block': 'A note block is crafted by placing red stone in the very center square and wooden planks all around that in a crafting table', - 'snow block': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'diamond leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sandstone': 'Red sandstone can be crafted by placing four red sand in a two by two grid in a crafting window.', - 'orange stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'slime block': 'A slime block can be crafted by placing slime balls in a three by three grid in a crafting window.', - 'bookshelf': 'A bookshelf is crafted by placing books across the middle row and wooden planks across the top and bottom rows', - 'cake': 'Cake can be crafted by placing three buckets of milk across the top row, sugar in the left middle, and right middle squares, an egg in the very center square, and three wheat across the bottom squares in a crafting table.', - 'wooden button': 'A wooden button can be crafted by placing a single wooden plank in a crafting window.', - 'chiseled quartz block': 'A chiseled quartz block can be obtained by placing a quartz slab on top of a quartz slab in a crafting table.', - 'stone button': 'A stone button can be crafted by placing a single piece of smooth stone in a crafting window.', - 'glow stone dust': 'Glow stone dust is obtained by breaking glow stone blocks.', - 'lime stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cobblestone wall': 'A cobblestone wall is crafted by placing six cobblestone across the bottom two rows in a crafting table.', - 'name tag': 'Name Tags can only be obtained in three ways. The first way is by finding it in a Dungeon chest. The second way is by fishing. The last way Name Tags can be obtained is by trading with the Librarian Villagers for twenty to twenty two Emeralds.', - 'gunpowder': 'Gunpowder can be randomly obtained by killing creepers.', - 'blaze powder': 'Blaze powder can be obtained by placing a blaze row in a crafting window.', - 'brewing stand': 'A brewing stand can be crafted by placing a blaze rod in the center square, and three cobblestone across the bottom row in a crafting table.', - 'torch': 'A torch can be crafted by placing a piece of coal on top of a stick.', - 'yellow wool': 'Yellow wool can be crafted by placing dandelion yellow next to any color wool in a crafting window.', - 'watermelon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest minecarts in abandoned mine shafts.', - 'wait disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'glistering melon': 'A glistering melon can be crafted by placing a melon in the very center square and surrounding it with eight gold nuggets in a crafting table.', - 'netherrack': 'Netherrack can be found commonly throughout the Nether dimension.', - 'leather chest plate': 'All chest places are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'wooden slab': 'A wooden slab can be crafted by placing three wooden planks in a row in a crafting table.', - 'nether brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ice': 'Ice can be found naturally in snow biomes. If broken, or placed near a heat source, ice will turn into water. To obtain an ice block, one would need to mine it with a silk touch pick ax.', - 'large fern': 'Large ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'nether brick slab': 'A nether brick slab can be crafted by placing three nether brick in a row in a crafting table.', - 'spruce wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'iron hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'fern': 'Ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'sea lantern': 'A sea lantern can be crafted by placing prismarine shards in the four corners of a crafting table, and then placing prismarine crystals in every other square.', - 'cookie': 'A cookie can be crafted by placing wheat, horizontally, on both sides of cocoa beans in a crafting table.', - 'melon seeds': 'Melon seeds can be crafted by placing a slice of melon in a crafting window.', - 'gold nugget': 'A gold nugget can be crafted by placing a single gold ingot into a crafting window. They can also be randomly obtained by killing a zombie pig men.', - 'red stone ore block': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'diamond helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'spruce fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'golden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'acacia wood plank': 'Acacia wood planks can be obtained by placing acacia wood in a crafting table', - 'diamond pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'lapis lazuli ore': 'Lapis Lazuli Ore can be only be obtained by using a pick ax with the silk touch enchant.', - 'raw mutton': 'Raw mutton can be obtained by killing a sheep.', - 'quartz stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'brick block': 'A brick block can be crafted by placing clay bricks in a two by two grid in a crafting window.', - 'cobblestone slab': 'A cobblestone slab can be crafted by placing three cobblestone blocks in a row in a crafting table.', - 'emerald ore': 'Emerald ore can only be found in extreme hills biomes between layers four and thirty-two. It can be mined with an iron pick ax or better to obtain an emerald. To obtain the ore itself, you will need a silk touch pick ax.', - 'yellow flower': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'jack o\'lantern': 'A jack o\'lantern can be crafted by placing a pumpkin on top of a torch in a crafting table.', - 'red stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'iron leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'pink stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'black dye': 'An ink sack is used as black dye in mine craft.', - 'wooden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'purple stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'detector rail': 'A detector rail can be crafted by placing a stone pressure plate in the very center square, red stone in the bottom middle square, and iron ingots in the far left and far right columns', - 'cyan wool': 'Cyan wool can be crafted by placing cyan dye next to any color wool in a crafting window.', - 'iron chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cobblestone': 'Cobblestone can be obtained by breaking stone with a pick ax.', - 'dark oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'creeper mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'carrot': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'rabbit hide': 'Rabbit hide can be randomly obtained by killing a rabbit.', - 'grass': 'When harvested with a regular shovel, grass turns into dirt. In order to obtain a grass block you will need to have a shovel with the silk touch enchant.', - 'strad disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'birch sapling': 'Birch saplings can be randomly obtained by breaking birch leaves.', - 'mossy stone': 'Mossy stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'pink dye': 'Pink dye can be crafted by placing bone meal next to rose red in a crafting window.', - 'red stone torch': 'A red stone torch is crafted by placing red stone on top of a torch in a crafting window.', - 'green stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'tall grass': 'Tall grass, which is called grass in a players inventory, spawns on grass blacks in certain biomes. Bonemeal can be used on a grass block to grow tall grass and occasionally flowers.', - 'black wool': 'Black wool can be crafted by placing an ink sac next to any color wool in a crafting window.', - 'wheat crops': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'ender pearl': 'Ender pearls can be randomly obtained by killing ender men.', - 'moss stone': 'Moss stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'fishing rod': 'A fishing rod is crafted by placing three sticks in a diagonal line, and then two string beneath the top right stick in a crafting window.', - 'bone meal': 'Bone meal can be crafted by placing a bone into a crafting window.', - 'quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'dark oak wood plank': 'Dark oak wood planks can be obtained by placing dark oak wood in a crafting table.', - 'powered rail': 'A powered rail can be crafted by placing a stick in the very center square, red stone in the bottom middle square, and gold ingots in the far left and far right columns', - 'beacon': 'A beacon can be obtained by placing a nether star in the very center square, three obsidian across the bottom row, and five glass in the remaining squares in a crafting table.', - 'blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'dark oak door': 'A Dark Oak Door can be crafted by placing six Dark Oak Planks down the first two columns.', - 'iron golem': 'An iron golem can be created by similarly to a snow golem. Place a pumpkin head on top of two iron blocks. Then place two more iron blocks on either side of the very center iron block.', - 'spruce wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'pink wool': 'Pink wool can be crafted by placing pink dye next to any color wool in a crafting window.', - 'fire charge': 'A fire charge can be crafted by placing blaze powder in the middle left square, coal in the very center square, and gunpowder in the bottom middle square in a crafting table.', - 'acacia door': 'An Acacia Door can be crafted by placing six Acacia Planks down the first two columns.', - 'iron pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chirp disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'arrow': 'An arrow can be crafted by placing flint in the top middle square, a stick in the very center square, and a feather in the bottom middle square in a crafting table.', - 'wooden ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'glass pane': 'A glass pane can be crafted by placing six glass blocks across the bottom two rows in a crafting table.', - 'gold helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'ender chest': 'An ender chest can be crafted by placing an eye of ender in the center square, and then surrounding that with eight obsidian blocks in a crafting table.', - 'light blue wool': 'Light blue wool can be crafted by placing light blue dye next to any color wool in a crafting window.', - 'string': 'String can be randomly obtained by killing spiders or by breaking cobwebs.', - 'red sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'purple wool': 'Purple wool can be crafted by placing purple dye next to any color wool in a crafting window.', - 'cyan stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'black stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'enchanted book': 'Enchanted books can be found in chests located in dungeons, strongholds, desert temples, jungle temples, and mine shafts.', - 'button': 'A button can be crafted by placing either a single piece of smooth stone or a single wooden plank in a crafting window.', - 'lime wool': 'Lime wool can be crafted by placing lime dye next to any color wool in a crafting window.', - 'coarse dirt': 'Coarse dirt can be obtained by breaking dirt in the Mega Taiga, Mesa, or Savanna biomes.', - 'ghast tear': 'Ghast tears can be rarely obtained by killing ghasts.', - 'mine cart with a furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'wheat': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'soul sand': 'Soul sand can be found commonly throughout the Nether dimension.', - 'brown mushroom': 'Brown mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'chainmail helmet': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'written book': 'A written book is created after a book and quill is signed.', - 'spruce sapling': 'Spruce saplings can be randomly obtained by breaking spruce leaves.', - 'oak sapling': 'Oak saplings can be randomly obtained by breaking oak leaves.', - 'inverted daylight sensor': 'An inverted daylight sensor can be created by right clicking on a daylight sensor.', - 'sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'red stone lamp': 'A red stone lamp can be crafted by placing glow stone in the very center square, and surrounding it with four red stone in a crafting table.', - 'crafting table': 'A crafting table is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'glow stone': 'Glow stone can be found on the ceiling in the Nether dimension.', - 'wooden pressure plate': 'A wooden pressure plate can be created by placing two wooden planks, horizontally, next to each other in a crafting window.', - 'charcoal': 'Charcoal can be obtained by burning wood blocks in a furnace.', - 'chainmail boots': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'ladder': 'A ladder is crafted by placing sticks in every square but the top middle and bottom middle square.', - 'mossy cobblestone': 'Mossy cobblestone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'golden pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'seeds': 'Wheat seeds can be randomly found by breaking tall grass.', - 'acacia fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'birch wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ward disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'music disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'enchanted golden apple': 'An enchanted golden apple is crafted by placing an apple in the very center square and surrounding it with eight gold blocks.', - 'white carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'diamonds pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chiseled red sandstone': 'Chiseled red sandstone can be crafted by placing a red sandstone slab on top of a red sandstone slab in a crafting window.', - 'stone brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'pressure plate': 'A pressure plate can be created by placing either two smooth stone or two wooden planks next to each other, horizontally, in a crafting window.', - 'jungle wood plank': 'Jungle wood planks can be obtained by placing jungle wood in a crafting table', - 'green wool': 'Green wool can be crafted by placing cactus green next to any color wool in a crafting window.', - 'sugar canes': 'Sugar canes occur naturally near water.', - 'bow': 'A bow can be crafted by placing three string in the rightmost column and then placing tree sticks in a less than sign pattern next to the string in a crafting table.', - 'lime carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'flint': 'Flint is randomly dropped while breaking gravel.', - 'black stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - }, - 'RECIPE_DE_DE': { - 'schneegolem': 'Ein Schneegolem kann erschaffen werden, indem ein Kürbis auf zwei auf dem Boden stehende Schneeblöcke gesetzt wird.', - 'quarzsäule': 'Eine Quarzsäule erhält man, indem in Minecraft ein Quarzblock auf einem Quarzblock platziert wird.', - 'feuerwerksrakete': 'Eine Feuerwerksrakete kann gecraftet werden, indem ein Feuerwerksstern in das linke mittlere Feld, ein Blatt Papier in das mittlere Feld und Schwarzpulver in das rechte mittlere Feld der Werkbank gelegt wird. Ähnlich wie bei einem Feuerwerksstern kann einer Feuerwerksrakete in der unteren Reihe zusätzliches Schwarzpulver hinzugefügt werden, um die Dauer der Rakete zu verlängern.', - 'kaninchenragout': 'Kaninchenragout kann gecraftet werden, indem ein Gekochtes Kaninchen in das obere mittlere Feld, eine Karotte in das linke mittlere Feld, eine Ofenkartoffel in das Feld ganz in der Mitte, eine beliebige Pilzart in das rechte mittlere Feld und eine Schüssel in des untere mittlere Feld platziert wird.', - 'kessel': 'Ein Kessel kann hergestellt werden, indem Eisenbarren in alle Felder der Werkbank mit Ausnahme des oberen mittleren Feldes und des Feldes ganz in der Mitte gelegt werden.', - 'steinschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'roter teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'buch und feder': 'Buch und Feder kann gecraftet werden, indem in der Werkbank ein Buch in das linke mittlere Feld, ein Tintenbeutel in das Feld ganz in der Mitte und eine Feder in das untere mittlere Feld platziert werden.', - 'rahmen': 'Ein Rahmen kann gecraftet werden, indem Leder in das Feld ganz in der Mitte platziert und dann von acht Stöcken umgeben wird.', - 'karte': 'Eine Karte kann gecraftet werden, indem ein Kompass in das Feld ganz in der Mitte platziert und dann von acht Blättern Papier umgeben wird.', - 'klebriger Kolben': 'Ein klebriger Kolben kann gecraftet werden, indem ein Schleimball im Craftingfeld über einem Kolben platziert wird.', - 'brot': 'Brot kann gecraftet werden, indem eine Reihe der Werkbank vollständig mit Weizen gefüllt wird.', - 'holzspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'schere': 'Eine Schere kann gecraftet werden, indem zwei Eisenbarren diagonal zueinander platziert werden.', - 'rohes rindfleisch': 'Rohes Rindfleisch wird beim Tod einer Kuh oder Mooshroom gedroppt.', - 'glatter roter sandstein': 'Glatter roter Sandstein kann gecraftet werden, indem im Craftingfeld vier rote Sandsteinblöcke in einem 2x2-Raster platziert werden.', - 'prismarinkristalle': 'Prismarinkristalle erhält man, indem Wächter und große Wächter besiegt werden.', - 'eichenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'holzschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'treppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'tropenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'aktivierungsschiene': 'Eine Aktivierungsschiene kann gecraftet werden, indem eine Redstone-Fackel in das Feld ganz in der Mitte, Stöcke darüber und darunter und dann sechs Eisenbarren in den übrigen Feldern der Werkbank platziert werden.', - 'ackerboden': 'Ackerboden kann hergestellt werden, indem der Boden mit einer Hacke bearbeitet wird.', - 'golderz': 'Golderz erhält man, indem Golderzblöcke mit einer Spitzhacke aus Eisen oder einem hochwertigerem Material abgebaut werden.', - 'andesit': 'Andesit kann mit einer Spitzhacke abgebaut werden, oder es lässt sich craften, indem in der Werkbank Diorit neben Bruchstein platziert wird.', - 'roter farbstoff': 'Roter Farbstoff kann gecraftet werden, indem eine Mohnblume in die Werkbank gelegt wird.', - 'eisenaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'hellblauer farbstoff': 'Hellblauer Farbstoff kann gecraftet werden, indem im Craftingfeld Lapislazuli neben Knochenmehl platziert wird.', - 'grauer farbstoff': 'Grauer Farbstoff kann gecraftet werden, indem im Craftingfeld Knochenmehl neben einem Tintenbeutel platziert wird.', - 'blau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'eiserne pferderüstung': 'Eine Pferderüstung kann zufällig in Verliesen, Netherfestungen, bei Schmieden, in Dschungeltempeln, Wüstentempeln und Truhen in Festungen gefunden werden.', - 'rot gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'ziegeltreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'goldene hose': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'schwarzeichenzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'witherschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'spinnenauge': 'Ein Spinnenauge droppt zufällig beim Töten von Spinnen oder Hexen.', - 'magenta gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'braun gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'kürbiskuchen': 'Ein Kürbiskuchen kann gecraftet werden, indem in der Werkbank ein Kürbis in das linke mittlere Feld, Zucker in das Feld ganz in der Mitte und ein Ei in das untere mittlere Feld platziert werden.', - 'schneeball': 'Einen Schneeball erhält man, indem Schnee mit einer Schaufel zerkleinert wird.', - 'jukebox': 'Eine Jukebox wird hergestellt, indem ein Diamant in einer Werkbank im mittleren Feld platziert und von Holzbrettern umgeben wird.', - 'sand': 'Sand erhält man, indem Sandblöcke zerkleinert werden.', - 'toter busch': 'Tote Büsche, auch nur Büsche genannt, werden mit einer Schere erhalten.', - 'ziegelstufe': 'Eine Ziegelstufe kann hergestellt werden, indem in einer Werkbank drei Ziegelstein-Blöcke in einer Reihe platziert werden.', - 'seerosenblatt': 'Seerosenblätter kommen natürlich auf Wasser in Sümpfen oder unterirdischen Seen vor.', - 'lederhose': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'bemooste bruchsteinmauer': 'Eine Bemooste Bruchsteinmauer wird gecraftet, indem sechs Bemooste Bruchsteine in die beiden unteren Reihen einer Werkbank platziert werden.', - 'schallplatte 11': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'violett gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'magenta gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'schallplatte mall': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'tropenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'diamantaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'leere karte': 'Eine Karte kann gecraftet werden, indem ein Kompass in das Feld ganz in der Mitte platziert und dann von acht Blättern Papier umgeben wird.', - 'steindruckplatte': 'Eine Steindruckplatte lässt sich craften, indem zwei glatte Steine horizontal nebeneinander in das Craftingfeld gelegt werden.', - 'falltür': 'Falltüren können entweder mit Holzbrettern oder Eisenbarren gecraftet werden. Um eine Holzfalltür zu craften, werden Holzbretter in alle Felder der beiden unteren Reihen platziert. Um eine Eisenfalltür zu craften, werden Eisenbarren in einem 2x2-Raster in einer Werkbank platziert.', - 'goldstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'schallplatte stall': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'redstone-kabel': 'Das Redstone-Kabel ist einfach Redstone, das auf dem Boden platziert wird.', - 'kolben': 'Ein Kolben kann gecraftet werden, indem ein Eisenbarren im Feld ganz in der Mitte, Redstone im unteren mittleren Feld, Holzbretter in allen Felder der oberen Reihe und Bruchstein in den übrigen Feldern platziert werden.', - 'weiß gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'antriebslore': 'Eine Antriebslore wird gecraftet, indem ein Ofen in einem Craftingfeld über einer Lore platziert wird.', - 'zucker': 'Zucker kann erhalten werden, indem Zuckerrohr in einer Werkbank platziert wird.', - 'kettenhemd': 'Kettenrüstung kann nur durch den Handel mit einem Dorfbewohner oder einem seltenen Drop von einer Kreatur erhalten werden.', - 'feder': 'Federn können zufällig durch das Töten von Hühnern erhalten werden.', - 'hellblau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'eichenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'steinspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'rosa teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'monsterspawner': 'Monsterspawner können in Minecraft nur durch Cheats erhalten werden.', - 'goldene karotte': 'Eine Goldene Karotte kann gecraftet werden, indem eine Karotte in das Feld ganz in der Mitte gelegt und dann von acht Goldklumpen umgeben wird.', - 'stock': 'Ein Stock kann gecraftet werden, indem in einem Craftingfeld ein Holzbrett über einem Holzbrett platziert wird.', - 'diamantblock': 'Ein Diamantblock kann gecraftet werden, indem Diamanten in allen Feldern einer Werkbank platziert werden.', - 'grün gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'gebratenes hühnchen': 'Rohes Hühnchen kann gebraten werden, indem es in einem Ofen geschmolzen wird. Alternativ dazu besteht die Chance, dass Gebratenes Hühnchen droppt, wenn ein brennendes Huhn stirbt.', - 'schallplatte 13': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'holzfalltür': 'Eine Holzfalltür wird gecraftet, indem Holzbretter in einer Werkbank in alle Felder der beiden unteren Reihen platziert werden.', - 'eichenzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'werkbank': 'Eine Werkbank kann gecraftet werden, indem Holzbretter in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'netherquarzerz': 'Netherquarzerz kann zufällig im Nether gefunden werden. Um das Erz anstelle von Netherquarz zu erhalten, muss eine mit Behutsamkeit verzauberte Spitzhacke verwendet werden.', - 'goldschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'grau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'hellblau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'diamantstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'steinhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'steinkohle': 'Steinkohle erhält man, indem Steinkohleblöcke mit einer mit Behutsamkeit verzauberten Spitzhacke abgebaut werden.', - 'schwarzeichenlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'tnt': 'TNT kann gecraftet werden, indem in einem Craftingfeld Schwarzpulver X-förmig platziert und dann Sand in alle übrigen Felder gelegt wird.', - 'ziegel': 'Ein Ziegel kann gecraftet werden, indem Ton in einem Ofen geschmolzen wird.', - 'kartoffel': 'Kartoffeln können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'oranger teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'tintenbeutel': 'Ein Tintenbeutel kann durch das Töten eines Tintenfischs erhalten werden.', - 'redstone': 'Redstone erhält man, indem Redstonerz mit einer Spitzhacke aus Eisen oder einem hochwertigerem Material abgebaut wird.', - 'schwarzeichenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'diorit': 'Diorit kann mit einer Spitzhacke abgebaut oder gecraftet werden, indem in der Werkbank in einem 2x2-Raster Bruchstein mit Netherquarz kombiniert wird.', - 'grau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'tropenholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'magenta wolle': 'Magenta Wolle kann gecraftet werden, indem in einem Craftingfeld Magenta Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'erde': 'Erde erhält man, indem Gras oder Erde mit einer Schaufel zerkleinert wird.', - 'rüstungsständer': 'Ein Rüstungsständer kann mit sechs Stöcken und einer Steinstufe gecraftet werden. Drei Stöcke werden in der obersten Reihe platziert. Die übrigen drei Stöcke werden jeweils im unteren linken und unteren rechten Feld sowie im Feld ganz in der Mitte platziert. Die Steinstufe wird wird im unteren mittleren Feld platziert.', - 'gebratener fisch': 'Gebratener Fisch wird erhalten, indem Fisch in einem Ofen gebraten wird.', - 'hebel': 'Ein Hebel kann gecraftet werden, indem in einem Craftingfeld ein Stock über Bruchstein platziert wird.', - 'leine': 'Eine Leine kann gecraftet werden, indem ein Schleimball in einer Werkbank in das Feld ganz in der Mitte und dann Fäden in das obere linke, obere mittlere, mittlere linke und untere rechte Feld platziert werden.', - 'gebratenes kaninchen': 'Gebratenes Kaninchen wird erhalten, indem Rohes Kaninchen in einem Ofen gebraten wird. Alternativ dazu besteht die Chance, dass Gebratenes Kaninchen droppt, wenn ein brennendes Kaninchen stirbt.', - 'tropenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'trichterlore': 'Eine Trichterlore wird gecraftet, indem ein Trichter in einer Werkbank über einer Lore platziert wird.', - 'fermentiertes Spinnenauge': 'Fermentiertes Spinnenauge kann gecraftet werden, indem in einer Werkbank ein brauner Pilz im mittleren linken Feld, Zucker im Feld ganz in der Mitte und ein Spinnenauge im unteren mittleren Feld platziert werden.', - 'roher fisch': 'Roher Fisch kann zufällig durch Angeln erhalten werden.', - 'braun gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'schild': 'Ein Schild kann gecraftet werden, indem Holzbretter in den beiden oberen Reihen und ein Stock im unteren mittleren Feld platziert werden.', - 'trichter': 'Ein Trichter kann gecraftet werden, indem in einer Werkbank eine Truhe im Feld ganz in der Mitte und dann Eisenbarren in jedem Feld mit Ausnahme des oberen mittleren, des linken unteren und rechten unteren Feldes platziert werden.', - 'lohenrute': 'Lohenruten können zufällig durch das Töten von Lohen erhalten werden.', - 'redstone-komparator': 'Ein Redstone-Komparator kann gecraftet werden, indem in der Werkbank drei glatte Steine in der unteren Reihe, ein Netzerquarz im Feld ganz in der Mitte und drei Redstone-Fackeln um den Netzerquarz herum platziert werden.', - 'knochen': 'Knochen können durch das Töten von Skeletten erhalten werden.', - 'goldene pferderüstung': 'Eine Pferderüstung kann zufällig in Verliesen, Netherfestungen, bei Schmieden, in Dschungeltempeln, Wüstentempeln und Truhen in Festungen gefunden werden.', - 'goldbeinschutz': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'schiene': 'Eine Schiene kann gecraftet werden, indem in einer Werkbank ein Stock im Feld ganz in der Mitte und Eisenbarren senkrecht in der ersten und letzten Spalte platziert werden.', - 'weizenkörner': 'Weizenkörner können durch die Ernte von Weizen erhalten werden.', - 'birkenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'violett gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'goldharnisch': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'lederstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'diamantschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'roter sand': 'Roter Sand kann in Tafelberg-Biomen gefunden werden.', - 'ranken': 'Ranken können nur mit einer Schere geerntet werden. Ranken wachsen natürlich an Dschungelbäumen oder in Sümpfen.', - 'glasflasche': 'Eine Glasflasche kann gecraftet werden, indem in einer Werkbank mit drei Glasblöcken ein V geformt wird.', - 'redstone-erz': 'Redstone-Erz kann in den unteren sechzehn Schichten der Karte gefunden werden. Wenn es mit einer Eisenspitzhacke oder einer Spitzhacke aus hochwertigerem Material zerstört wird, droppt es eine gewisse Anzahl von Redstone. Um das Erz an und für sich zu erhalten, muss eine Spitzhacke mit der Verzauberung Behutsamkeit verwendet werden.', - 'smaragdblock': 'Ein Smaragdblock kann gecraftet werden, indem neun Smaragde in einem 3x3-Raster in einer Werkbank platziert werden.', - 'granit': 'Granit kann mit einer Spitzhacke abgebaut oder gecraftet werden, indem in der Werkbank Diorit und ein Netherquarz nebeneinander platziert werden.', - 'braune wolle': 'Braune Wolle kann gecraftet werden, indem in einem Craftingfeld Brauner Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'goldener apfel': 'Ein Goldener Apfel kann gecraftet werden, indem ein Apfel in das Feld ganz in der Mitte gelegt und dann von acht Goldbarren umgeben wird.', - 'birkenlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'weiße wolle': 'Weiße Wolle kann gecraftet werden, indem im Craftingfeld vier Fäden in einem 2x2-Raster platziert werden. Sie kann auch gecraftet werden, indem in einem Craftingfeld Knochenmehl neben Wolle einer beliebigen Farbe platziert wird.', - 'violetter teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'gebrannter ton': 'Gebrannter Ton kann gecraftet werden, indem ein Tonblock in einem Ofen geschmolzen wird.', - 'zombieschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'eisenfalltür': 'Eine Eisenfalltür kann gecraftet werden, indem Eisenbarren in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'blumentopf': 'Ein Blumentopf kann gecraftet werden, indem in einer Werkbank drei Ziegel in V-Form platziert werden.', - 'eisenerz': 'Eisenerz kann erhalten werden, indem Eisenerzblöcke mit einer Spitzhacke aus Stein oder einem hochwertigerem Material abgebaut werden.', - 'tropenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'birkenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'tropenholztür': 'Eine Tropenholztür kann gecraftet werden, indem sechs Tropenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'goldaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'packeis': 'Packeis kann in der seltenen Eiszapfentundra gefunden und nur mit einem Werkzeug mit der Verzauberung Behutsamkeit abgebaut werden.', - 'hellblauer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'spender': 'Ein Spender kann gecraftet werden, indem Redstone im mittleren unteren Feld und Bruchstein in den übrigen Feldern außer im Feld ganz in der Mitte platziert werden.', - 'truhe': 'Eine Truhe kann gecraftet werden, indem Holzbretter in alle Felder einer Werkbank mit Ausnahme des Feldes ganz in der Mitte platziert werden.', - 'rohes hühnchen': 'Rohes Hühnchen wird beim Tod eines Huhns gedroppt.', - 'roher lachs': 'Roher Lachs kann zufällig durch Angeln erhalten werden.', - 'haken': 'Ein Haken kann gecraftet werden, indem in einer Werkbank ein Eisenbarren über einem Stock über einem Holzbrett platziert wird.', - 'eichenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'befehlsblocklore': 'Eine Befehlsblocklore kann nur durch Cheats erhalten werden.', - 'enderauge': 'Ein Enderauge kann gecraftet werden, indem im Craftingfeld Lohenstaub neben einer Enderperle platziert wird.', - 'kohleblock': 'Ein Kohleblock kann gecraftet werden, indem Kohle in einem 3x3-Raster in einem Craftingfeld platziert wird.', - 'netherstern': 'Ein Netherstern kann erhalten werden, indem der Wither besiegt wird.', - 'kies': 'Kies erhält man, indem Kiesblöcke zerkleinert werden.', - 'blaue wolle': 'Blaue Wolle kann gecraftet werden, indem im Craftingfeld Blauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'netherquarz': 'Netzerquarz kann erhalten werden, indem Netzquarzerz in einem Ofen geschmolzen wird.', - 'verrottetes fleisch': 'Verrottetes Fleisch kann zufällig durch das Töten von Zombies erhalten werden.', - 'magenta teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'weiß gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'birkenholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'karotten': 'Karotten können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'violetter farbstoff': 'Violetter Farbstoff kann gecraftet werden, indem im Craftingfeld Lapislazuli neben Rotem Farbstoff platziert wird.', - 'lapislazuliblock': 'Ein Lapislazuliblock kann erhalten werden, indem eine Werkbank vollständig mit Lapislazuli ausgefüllt wird.', - 'obsidian': 'Obsidian kann mit einer Diamantspitzhacke abgebaut oder hergestellt werden, indem Wasser über Lava platziert wird. ', - 'schallplatte mellohi': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'graue wolle': 'Graue Wolle kann gecraftet werden, indem im Craftingfeld Grauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'redstonetruhe': 'Eine Redstonetruhe kann gecraftet werden, indem in einem Craftingfeld ein Haken neben einer Truhe platziert wird.', - 'hellgrau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'eisenspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'roter pilz': 'Rote Pilze können natürlich in schlecht beleuchteten Bereichen, Pilzbiomen oder im Nether gefunden werden.', - 'kugelfisch': 'Ein Kugelfisch kann zufällig durch Angeln erhalten werden.', - 'smaragd': 'Smaragde können durch den Abbau von Smaragderz gewonnen.', - 'holzschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'goldhelm': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'melone': 'Eine Melone kommt natürlich in Dschungeln vor oder kann mithilfe aus in Güterloren in verlassenen Minen gefundenen Melonenkernen angebaut werden.', - 'tonblock': 'Ton wird gewöhnlich auf dem Boden von Flüssen und Seen in flachen, runden Stellen gefunden. Tonblöcke können gewöhnlich auch in Sümpfen gefunden werden.', - 'amboss': 'Ein Amboss kann gecraftet werden, indem in einer Werkbank drei Eisenblöcke in die oberste Reihe, ein Eisenbarren in das Feld ganz in der Mitte und dann drei Eisenbarren in der unteren Reihe platziert werden.', - 'tageslichtsensor': 'Ein Tageslichtsensor kann gecraftet werden, indem in einer Werkbank drei Mal Glas in der oberen Reihe, drei Netherquarze in der mittleren Reihe und drei Holzstufen in der unteren Reihe platziert werden.', - 'sandstein': 'Sandstein kann in Wüsten gewonnen oder durch die Kombination von Sand in einem 2x2-Raster gecraftet werden.', - 'lederjacke': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'schwarz gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'hellgrün gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'tnt-lore': 'Eine TNT-Lore wird gecraftet, indem ein TNT in einer Werkbank über einer Lore platziert wird.', - 'uhr': 'Eine Uhr wird hergestellt, indem ein Redstone in einer Werkbank im mittleren Feld platziert und von vier Goldbarren umgeben wird.', - 'schwarzer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'kakao': 'Kakao entsteht aus Kakaopflanzen, die im Dschungel natürlich vorkommen. Kakaobohnen werden in Minecraft als Brauner Farbstoff verwendet.', - 'goldbarren': 'Goldbarren können erhalten werden, indem Golderz in einem Ofen geschmolzen wird.', - 'steinziegelstufe': 'Eine Steinziegelstufe kann hergestellt werden, indem in einer Werkbank drei Steinziegel in einer Reihe platziert werden.', - 'clownfisch': 'Ein Clownfisch kann zufällig durch Angeln erhalten werden.', - 'kürbiskerne': 'Kürbiskerne können gecraftet werden, indem ein Kürbis in einem Craftingfeld platziert wird.', - 'bemooster steinziegel': 'Ein bemooster Steinziegel kann gecraftet werden, indem Ranken in einer Werkbank im Feld neben Steinziegeln platziert werden. Ein bemooster Steinziegel kann auch natürlich in Festungen vorkommen.', - 'spinnennetz': 'Spinnennetze erhält man durch die Verwendung einer Schere oder eines Schwerts, das mit Behutsamkeit verzaubert ist.', - 'milcheimer': 'Ein Milcheimer kann durch einen Rechtsklick auf eine Kuh mit einem Eiseneimer erhalten werden.', - 'eisenhelm': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'gelb gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'hellgrau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'diamant': 'Diamanten erhält man, indem Diamanterz mit einer Spitzhacke aus Eisen oder einem hochwertigerem Material abgebaut wird.', - 'steinschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'bruchsteintreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'bett': 'Ein Bett kann gecraftet werden, indem in einer Werkbank drei Mal Wolle in der oberen Reihe und drei Holzbretter in der mittleren Reihe platziert werden.', - 'birkenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'quarzstufe': 'Eine Quarzstufe kann hergestellt werden, indem in einer Werkbank drei Quarzblöcke in einer Reihe platziert werden.', - 'schwamm': 'Schwämme können durch Töten eines großen Wächters gewonnen oder zufällig in Ozeanmonumenten gefunden werden.', - 'skelettschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'eimer': 'Ein Eimer kann hergestellt werden, indem in einer Werkbank drei Eisenbarren V-förmig platziert werden.', - 'diamantschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'goldschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'fichtenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'eisengitter': 'Ein Eisengitter kann gecraftet werden, indem sechs Eisenbarren in die beiden unteren Reihen einer Werkbank platziert werden, Ein Eisengitter kann auch natürlich in Festungen vorkommen.', - 'rohes kaninchen': 'Rohes Kaninchen kann zufällig durch das Töten eines Kaninchens erhalten werden.', - 'gelber teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'karottenrute': 'Eine Karottenrute kann gecraftet werden, indem im Craftingfeld eine Angel im mittleren linken Feld und eine Karotte im unteren mittleren Feld platziert werden.', - 'rohes schweinefleisch': 'Rohes Schweinefleisch kann durch das Töten eines Schweins erhalten werden.', - 'ofen': 'Ein Ofen kann gecraftet werden, indem Bruchstein in alle Felder einer Werkbank mit Ausnahme des Feldes ganz in der Mitte platziert werden.', - 'netherziegelzaun': 'Ein Netzziegelzaun kann gecraftet werden, indem sechs Netherziegel in die beiden unteren Reihen einer Werkbank platziert werden.', - 'zaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'diamantene pferderüstung': 'Eine Pferderüstung kann zufällig in Verliesen, Netherfestungen, bei Schmieden, in Dschungeltempeln, Wüstentempeln und Truhen in Festungen gefunden werden.', - 'rote sandsteinstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'birkenholzbrett': 'Birkenholzbretter können erhalten werden, indem Birkenholz in einer Werkbank platziert wird.', - 'grundgestein': 'Grundgestein kann in Minecraft nur durch Cheats gewonnen werden, Es ist der unterste Block des Spiels.', - 'sattel': 'Sättel können nicht gecraftet werden, sondern nur in Truhen in Verliesen, verlassenen Minenschächten, Netherfestungen, Wüstentempeln oder Dschungeltempeln gefunden werden.', - 'hellgrauer farbstoff': 'Hellgrauer Farbstoff kann gecraftet werden, indem im Craftingfeld zwei Mal Knochenmehl in einer senkrechten Reihe neben einem Tintenbeutel platziert wird.', - 'tropenbaumlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'schallplatte blocks': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'kürbis': 'Kürbisse sind in den meisten Biomen selten auf Grasblöcken zu finden.', - 'ofenkartoffel': 'Eine Ofenkartoffel kann erhalten werden, indem eine Kartoffel in einem Ofen geschmolzen wird.', - 'leder': 'Leder kann zufällig durch das Töten von Kühen oder Pferden erhalten werden.', - 'hellgrauer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'eisenstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'endstein': 'Endstein kann naturgemäß in der Ende-Dimension gefunden werden.', - 'kettenhose': 'Eine Kettenrüstung kann durch den Handel mit einem Dorfbewohner oder einen seltenen Drop von einer Kreatur erhalten werden.', - 'hasenpfote': 'Eine Hasenpfote kann in seltenen Fällen beim Töten eines Hasens erhalten werden.', - 'glas': 'Glas wird erhalten, indem Sand in einem Ofen geschmolzen wird.', - 'stein': 'Stein wird hergestellt, indem Bruchstein in einem Ofen geschmolzen wird.', - 'prismarin': 'Prismarin kann gecraftet werden, indem Prismarinscherben in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'kompass': 'Ein Kompass wird hergestellt, indem ein Redstone in einer Werkbank im mittleren Feld platziert und von vier Eisenbarren umgeben wird.', - 'grün gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'goldhose': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'befehlsblock': 'Befehlsblöcke können in Minecraft nur durch Cheats erhalten werden.', - 'werfer': 'Ein Werfer kann hergestellt werden, indem ein Bogen im mittleren Feld, Redstone direkt darunter und Bruchstein in allen anderen Feldern platziert werden.', - 'giftige kartoffel': 'Eine Giftige Kartoffel droppt zufällig beim Ernten von Kartoffeln.', - 'apfel': 'Äpfel droppen zufällig von Eichen und Schwarzeichenlaub. Sie können auch zufällig in Truhen in Festungen und Dörfern gefunden werden.', - 'rote blume': 'Mohn kann naturgemäß auf Gras gefunden oder zufällig hergestellt werden, indem Knochenmehl auf Gras angewandt wird.', - 'magenta farbstoff': 'Magenta Farbstoff kann gecraftet werden, indem in einem Craftingfeld Violetter Farbstoff neben Rosa Farbstoff platziert wird.', - 'brauner teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'prismarinscherbe': 'Prismarinscherben können durch das Besiegen von Wächtern und großen Wächtern erhalten werden.', - 'redstone-block': 'Ein Redstone-Block kann gecraftet werden, indem neun Redstones in einem 3x3-Raster in einer Werkbank platziert werden.', - 'gelb gefärbte glasscheibe': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'löwenzahngelb': 'Löwenzahngelb entspricht dem Gelben Farbstoff in Minecraft. Es kann gecraftet werden, indem ein Löwenzahn oder eine Sonnenblume in einem Craftingfeld platziert wird.', - 'akazienholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'sandsteinstufe': 'Eine Sandsteinstufe kann hergestellt werden, indem in einer Werkbank drei Sandstein-Blöcke in einer Reihe platziert werden.', - 'grauer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'polierter granit': 'Polierter Granit kann gecraftet werden, indem vier Mal Granit in einem 2x2-Raster in einer Werkbank platziert wird.', - 'lore': 'Eine Lore kann gecraftet werden, indem fünf Eisenbarren U-förmig in einer Werkbank platziert werden.', - 'braun gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'türkis gefärbte glasscheibe': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'buch': 'Ein Buch wird mithilfe eines 2x2-Rasters in einem Craftingfeld hergestellt, bei dem in das rechte untere Feld Leder und in allen anderen Feldern Papier platziert wird.', - 'güterlore': 'Eine Güterlore wird gecraftet, indem eine Truhe in einem Craftingfeld über einer Lore platziert wird.', - 'akaziensetzling': 'Akaziensetzlinge können zufällig erhalten werden, indem Akazienlaub zerstört wird.', - 'papier': 'Brot kann gecraftet werden, indem in einer Werkbank drei Mal Zuckerrohr in einer Reihe platziert wird.', - 'türkis gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'pilzsuppe': 'Die Pilzsuppe oder der Pilzeintopf wird gecraftet, indem in einer Werkbank ein Roter Pilz im mittleren linken Feld, ein Brauner Pilz im mittleren Feld und eine Schüssel im unteren mittleren Feld platziert werden.', - 'netherziegel': 'Netherziegel kann mit einer Spitzhacke abgebaut oder gecraftet werden, indem in der Werkbank in einem 2x2-Raster vier Netherziegel platziert werden.', - 'magmacreme': 'Magmacreme kann gecraftet werden, indem in einem Craftingfeld Lohenstaub neben einem Schleimball platziert wird.', - 'schnee': 'Schnee kann gecraftet werden, indem Schneebälle in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'oranger farbstoff': 'Oranger Farbstoff kann gecraftet werden, indem im Craftingfeld Roter Farbstoff neben einem Gelben Farbstoff platziert wird.', - 'trank': 'Ein Trank wird mithilfe eines Braustands, eines Kessels und Wasserflaschen hergestellt.', - 'hellgrün gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'weiß gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'boot': 'Ein Boot kann erhalten werden, indem fünf Holzbretter U-förmig platziert werden.', - 'dunkler prismarin': 'Dunkle Prismarine können gecraftet werden, indem ein Tintenbeutel im mittleren Feld platziert und dann von acht Prismarinscherben umgeben wird.', - 'eichenholztür': 'Eine Eichenholztür kann gecraftet werden, indem sechs Eichenbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'eichenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'rote wolle': 'Rote Wolle kann gecraftet werden, indem im Craftingfeld Roter Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'gebratenes hammelfleisch': 'Gebratenes Hammelfleisch wird erhalten, indem Rohes Hammelfleisch in einem Ofen gebraten wird. Alternativ dazu droppen ein bis zwei Stücke Gebratenes Hammelfleisch, wenn ein brennendes Schaf stirbt.', - 'schwarzeichenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'eisentür': 'Eine Eisentür kann gecraftet werden, indem sechs Eisenbarren in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'gemälde': 'Ein Gemälde wird gecraftet, indem Wolle im mittleren Feld platziert und von acht Stöcken umgeben wird.', - 'fichtennadeln': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'rosa gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'akazienholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'schwarzeichenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'gemeißelter sandstein': 'Gemeißelter Sandstein kann hergestellt werden, indem im Craftingfeld eine Sandsteinstufe über einer anderen platziert wird.', - 'eichenholzbrett': 'Eichenholzbretter können erhalten werden, indem Eichenholz in einer Werkbank platziert wird.', - 'gebratener lachs': 'Gebratener Lachs wird erhalten, indem Lachs in einem Ofen gebraten wird.', - 'eisenschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'zaubertisch': 'Ein Zaubertisch kann gecraftet werden, indem in der Werkbank ein Buch in das obere mittlere Feld, Diamanten in das mittlere linke und mittlere rechte Feld und Obsidian ganz in die Mitte und in alle Felder der untersten Reihe platziert werden.', - 'redstone-verstärker': 'Ein Redstone-Verstärker kann gecraftet werden, indem glatter Stein in allen drei Feldern der untersten Reihe, Redstone ganz in der Mitte und Redstone-Fackeln links und rechts vom Redstone platziert werden.', - 'schallplatte far': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'grüner teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'eisenbarren': 'Eisenbarren können erhalten werden, indem Eisenerz in einem Ofen geschmolzen wird.', - 'orange wolle': 'Orange Wolle kann gecraftet werden, indem im Craftingfeld Oranger Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'tropenbaumsetzling': 'Tropenbaumsetzlinge können zufällig erhalten werden, indem Tropenbaumlaub zerstört wird.', - 'steinstufe': 'Eine Steinstufe kann hergestellt werden, indem in einer Werkbank drei Stein-Blöcke in einer Reihe platziert werden.', - 'hellblau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'türkiser farbstoff': 'Türkiser Farbstoff kann gecraftet werden, indem im Craftingfeld Lapislazuli neben Kaktusgrün platziert wird.', - 'steak': 'Rohes Rindfleisch kann zu Steak zubereitet werden, indem es in einem Ofen geschmolzen wird. Alternativ dazu besteht die Chance, dass Steak droppt, wenn eine brennende Kuh oder Moo stirbt.', - 'orange gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'blau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'fichtenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'kohle': 'Kohle erhält man, indem Steinkohleblöcke mit einer Spitzhacke aus Holz oder aus einem hochwertigerem Material abgebaut werden.', - 'kartoffeln': 'Kartoffeln können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'hellgrau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'zauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'ei': 'Eier werden von Hühnern zufällig gelegt. Das Werfen eines Eis kann mitunter ein neues Küken spawnen.', - 'fichtenholzbrett': 'Fichtenholzbretter können erhalten werden, indem Fichtenholz in einer Werkbank platziert wird.', - 'orange gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'akazienholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'hellgraue wolle': 'Hellgrau Wolle kann gecraftet werden, indem im Craftingfeld Hellgrauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'strohballen': 'Ein Strohballen kann gecraftet werden, indem Weizen in einem 3x3-Raster in einer Werkbank platziert wird.', - 'ton': 'Ton wird erhalten, indem man Tonblöcke mit einer nicht mit Behutsamkeit verzauberten Spitzhacke abbaut.', - 'schüssel': 'Eine Schüssel kann hergestellt werden, indem in einer Werkbank drei Holzbretter V-förmig platziert werden.', - 'lederkappe': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'rosa gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'diamantbrustpanzer': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'grau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'schneemann': 'Ein Schneegolem kann erschaffen werden, indem ein Kürbis auf zwei auf dem Boden stehende Schneeblöcke gesetzt wird.', - 'diamanterz': 'Diamanterz kann in den unteren sechzehn Schichten der Karte gefunden werden. Diamanterz kann mit einer Spitzhacke aus Eisen oder hochwertigerem Material zerbrochen werden. Damit wird das Diamanterz zu einem Diamanten. Um das Erz zu erhalten, muss eine Spitzhacke mit der Verzauberung Behutsamkeit verwendet werden.', - 'banner': 'Ein Banner kann gecraftet werden, indem sechs Mal Wolle in die beiden oberen Reihen und ein Stock im unteren mittleren Feld platziert werden. Das Banner nimmt die Farbe der ausgewählten Wolle an.', - 'steinaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'feuerwerksstern': 'Ein Feuerwerksstern kann gecraftet werden, indem in der Werkbank Schwarzpulver in das linke mittlere und Farbstoff einer beliebigen Farbe in das Feld ganz in der Mitte platziert werden. Außerdem kann ein Feuerwerksstern auch mit optionalen Materialien wie Diamanten, Glowstonestaub oder Federn gecraftet werden, die in der Werkbank direkt unterhalb des Farbstoffes platziert werden müssen.', - 'netherwarze': 'Netherwarzen treten natürlich in Pflanzenform in Netherfestungen auf.', - 'rot gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'quarzblock': 'Ein Quarzblock kann gecraftet werden, indem vier Mal Netherquarz in einem 2x2-Raster in einer Werkbank platziert wird.', - 'mohn': 'Mohn kann naturgemäß auf Gras gefunden oder zufällig hergestellt werden, indem Knochenmehl auf Gras angewandt wird.', - 'akazienholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'kaktus': 'Kaktus kann naturgemäß in der Wüsten-Biomen gefunden werden. ', - 'fichtenholztür': 'Eine Fichtenholztür kann gecraftet werden, indem sechs Fichtenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'schallplatte cat': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'feuerzeug': 'Ein Feuerzeug kann gecraftet werden, indem im Craftingfeld ein Eisenbarren links von einem Feuerstein platziert wird.', - 'schleimball': 'Schleimbälle droppen zufällig beim Töten von Schleimen.', - 'gebratenes schweinefleisch': 'Gebratenes Schweinefleisch kann erhalten werden, indem Rohes Schweinefleisch in einem Ofen gebraten oder ein Schwein angezündet wird.', - 'polierter andesit': 'Polierter Andesit kann gecraftet werden, indem vier Mal Andesit in einem 2x2-Raster in einer Werkbank platziert wird.', - 'prismarinziegel': 'Prismarinziegel können gecraftet werden, indem Prismarinscherben in einem 3x3-Raster in einer Werkbank platziert werden.', - 'wither': 'Ein Wither kann erschaffen werden, indem man drei Witherskelettschädel auf Seelensand gibt, der wiederum T-förmig auf dem Boden platziert wird.', - 'hellgrüner farbstoff': 'Hellgrüner Farbstoff kann gecraftet werden, indem im Craftingfeld Kaktusgrün neben Knochenmehl platziert wird.', - 'blauer Teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'tür': 'Eine Tür kann gecraftet werden, indem sechs Bretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'stolperdraht': 'Stolperdraht ist einfach eine Schnur neben einem Haken.', - 'türkiser teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'polierter diorit': 'Polierter Diorit kann gecraftet werden, indem vier Mal Diorit in einem 2x2-Raster in einer Werkbank platziert wird.', - 'eisenblock': 'Ein Eisenblock kann gecraftet werden, indem Eisenbarren in einem 3x3-Raster in einer Werkbank platziert werden.', - 'akazienlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'schwarzeichensetzling': 'Schwarzeichensetzlinge können zufällig erhalten werden, indem Schwarzeichenlaub zerstört wird.', - 'diamantenhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'löwenzahn': 'Löwenzahn wächst natürlich auf Gras oder kann zufällig hergestellt werden, indem Knochenmehl auf Gras verwendet wird.', - 'lapislazuli': 'Kann erhalten werden, indem Lapislazulierz mit einer Spitzhacke aus Stein oder hochwertigerem Material abgebaut wird.', - 'zuckerrohr': 'Zuckerrohr kann naturgemäß in der Nähe von Wasser gefunden werden.', - 'birkenholztür': 'Eine Birkenholztür kann gecraftet werden, indem sechs Birkenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'kaktusgrün': 'Kaktusgrün kann gecraftet werden, indem ein Kaktus in einem Ofen geschmolzen wird.', - 'goldblock': 'Ein Goldblock kann gecraftet werden, indem Goldbarren in einem 3x3-Raster in einer Werkbank platziert werden.', - 'glatter sandstein': 'Glatter Sandstein kann gecraftet werden, indem in einem Craftingfeld vier Mal Sandstein in einem 2x2-Raster platziert wird.', - 'magenta gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'notenblock': 'Ein Notenblock wird gecraftet, indem ein Redstone in einer Werkbank im mittleren Feld platziert und von Holzbrettern umgeben wird.', - 'schnee-block': 'Schnee kann gecraftet werden, indem Schneebälle in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'kreaturenschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'diamantbeinschutz': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'roter sandstein': 'Roter Sandstein kann gecraftet werden, indem vier Mal Roter Sand in einem 2x2-Craftingfeld platziert wird.', - 'orange gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'schleimblock': 'Ein Schleimblock kann gecraftet werden, indem Schleimbälle in einem 3x3-Raster in einem Craftingfeld platziert werden.', - 'bücherregal': 'Ein Bücherregal wird hergestellt, indem Bücher über die mittlere Reihe und Holzbretter in der oberen und unteren Reihe platziert werden.', - 'kuchen': 'Kuchen kann gecraftet werden, indem in der Werkbank drei Eimer Milch in der obersten Reihe, Zucker im linken mittleren und im rechten mittleren Feld, ein Ei im Feld ganz in der Mitte und drei Mal Weizen in der untersten Reihe platziert werden.', - 'holzknopf': 'Ein Holzknopf kann gecraftet werden, indem ein einziges Holzbrett in einem Craftingfeld platziert wird.', - 'gemeißelter quarzblock': 'Ein Gemeißelter Quarzblock kann erhalten werden, indem in einer Werkbank eine Quarzstufe über einer anderen platziert wird.', - 'steinknopf': 'Ein Steinknopf kann gecraftet werden, indem ein einziger glatter Stein in einem Craftingfeld platziert wird.', - 'glowstonestaub': 'Glowstonestaub wird durch den Abbau von Glowstoneblöcken erhalten.', - 'hellgrün gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'bruchsteinmauer': 'Eine Bruchsteinmauer wird gecraftet, indem sechs Bruchsteine in die beiden unteren Reihen einer Werkbank platziert werden.', - 'namensschild': 'Namensschilder können nur auf drei Arten erhalten werden. Sie können in einer Truhe in einem Verlies gefunden werden. Beim Angeln können Namensschilder auch erhalten werden. Der Tausch gegen zwanzig bis zweiundzwanzig Smaragde bei einem Bibliothekar-Dorfbewohner stellt die letzte Möglichkeit für den Erwerb eines Namensschildes dar.', - 'schwarzpulver': 'Schwarzpulver kann zufällig durch das Töten von Creepern erhalten werden.', - 'lohenstaub': 'Lohenstaub kann erhalten werden, indem eine Lohenrute in einer Werkbank platziert wird.', - 'braustand': 'Ein Braustand kann gecraftet werden, indem eine Lohenrute ganz in die Mitte und drei Bruchsteine in der untersten Reihe der Werkbank platziert werden.', - 'fackel': 'Ein Fackel kann gecraftet werden, indem ein Stück Kohle über einem Stock platziert wird.', - 'gelbe wolle': 'Gelbe Wolle kann gecraftet werden, indem im Craftingfeld Gelber Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'schallplatte wait': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'glitzernde melone': 'Eine Glitzernde Melone kann hergestellt werden, indem eine Melone in einer Werkbank im mittleren Feld platziert und von acht Goldklumpen umgeben wird.', - 'netherrack': 'Netherrack oder Netherstein kann gewöhnlich in der gesamten Nether-Dimension gefunden werden.', - 'holzstufe': 'Eine Holzstufe kann hergestellt werden, indem in einer Werkbank drei Holzbretter in einer Reihe platziert werden.', - 'netherziegeltreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'eis': 'Eis kommt natürlicherweise in Schnee-Biomen vor. Wenn es zerbrochen oder neben einer Hitzequelle platziert wird, schmilzt es zu Wasser. Um einen Eisblock zu erhalten, muss er mit einer Spitzhacke mit der Verzauberung Behutsamkeit abgebaut werden.', - 'großer farn': 'Großer Farn kommt natürlicherweise in Dschungel-, Taiga- und Riesentaiga-Biomen vor.', - 'netherziegelstufe': 'Eine Netherziegelstufe kann hergestellt werden, indem in einer Werkbank drei Netherziegel in einer Reihe platziert werden.', - 'fichtenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'eisenhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'farn': 'Farn kommt natürlicherweise in Dschungel-, Taiga- und Riesentaiga-Biomen vor.', - 'seelaterne': 'Eine Seelaterne kann gecraftet werden, indem Prismarinscherben in die vier Ecken einer Werkbank platziert und in die anderen Felder Prismarinkristalle gegeben werden.', - 'keks': 'Ein Keks kann gecraftet werden, indem in der Werkbank in einer Reihe Weizen links und rechts von Kakaobohnen platziert wird.', - 'melonenkerne': 'Melonenkerne können gecraftet werden, indem eine Melonenscheibe in einem Craftingfeld platziert wird.', - 'goldklumpen': 'Goldklumpen können gecraftet werden, indem ein einziger Goldbarren in einem Craftingfeld platziert wird. Außerdem können sie zufällig durch das Töten eines Zombie-Pigmen erhalten werden.', - 'diamanthelm': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'fichtenholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'goldhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'akazienholzbrett': 'Akazienholzbretter können erhalten werden, indem Akazienholz in einer Werkbank platziert wird.', - 'diamantspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'lapislazulierz': 'Lapislazulierz kann nur erhalten werden, indem eine Spitzhacke mit der Verzauberung Behutsamkeit verwendet wird.', - 'rohes hammelfleisch': 'Rohes Hammelfleisch kann durch das Töten eines Schafs erhalten werden.', - 'quarztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'ziegelstein-block': 'Ein Ziegelstein-Block kann gecraftet werden, indem Tonziegel in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'bruchsteinstufe': 'Eine Bruchsteinstufe kann hergestellt werden, indem in einer Werkbank drei Bruchstein-Blöcke in einer Reihe platziert werden.', - 'smaragderz': 'Smaragderz kann nur im Untergrund von Extremen Bergen zwischen den Schichten vier und zweiunddreißig gefunden werden. Es kann mit einer Eisenspitzhacke oder besser abgebaut werden, um Smaragde zu erhalten. Um das Erz selbst zu erhalten, wird eine Spitzhacke mit der Verzauberung Behutsamkeit benötigt.', - 'gelbe blume': 'Löwenzahn wächst natürlich auf Gras oder kann zufällig hergestellt werden, indem Knochenmehl auf Gras verwendet wird.', - 'kürbislaternen': 'Eine Kürbislaterne wird gecraftet, indem ein Kürbis in einer Werkbank über einer Fackel platziert wird.', - 'rot gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'eisenbeinschutz': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'rosa gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'schwarzer farbstoff': 'Ein Tintelbeutel wird in Minecraft als Schwarzer Farbstoff verwendet.', - 'holzhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'violett gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'sensorschiene': 'Eine Sensorschiene kann gecraftet werden, indem eine Steindruckplatte im Feld ganz in der Mitte, Redstone im unteren mittleren Feld und Eisenbarren in den Feldern der rechten und linken Spalte platziert werden.', - 'türkise wolle': 'Türkise Wolle kann gecraftet werden, indem im Craftingfeld Türkiser Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'eisenbrustpanzer': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'bruchstein': 'Bruchstein kann erhalten werden, indem Stein mit einer Spitzhacke abgebaut wird.', - 'schwarzeichenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'creeperkopf': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'karotte': 'Karotten können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'kaninchenfell': 'Kaninchenfell kann zufällig durch das Töten eines Kaninchens erhalten werden.', - 'gras': 'Wenn Gras mit einer gewöhnlichen Schaufel geerntet wird, verwandelt es sich in Erde. Um einen Grasblock zu erhalten, muss eine Schaufel mit der Verzauberung Behutsamkeit verwendet werden.', - 'schallplatte strad': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'birkensetzlinge': 'Birkensetzlinge können zufällig erhalten werden, indem Birkenlaub zerstört wird.', - 'moosstein': 'Bemooster Bruchstein oder früher Moosstein kann gecraftet werden, indem Ranken in einer Werkbank im Feld neben einem Bruchstein platziert werden. Er kann auch natürlicherweise in verschiedenen Verliesen gefunden werden.', - 'rosa farbstoff': 'Rosa Farbstoff kann gecraftet werden, indem im Craftingfeld Knochenmehl neben Rotem Farbstoff platziert wird.', - 'redstone-fackel': 'Eine Redstone-Fackel wird gecraftet, indem ein Redstone in einem Craftingfeld über einer Fackel platziert wird.', - 'grün gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'hohes gras': 'Hohes Gras, welches im Inventar Gras genannt wird, wächst auf Grasblöcken in bestimmten Biomen. Knochenmehl kann auf einem Grasblock verwendet werden, um Hohes Gras oder gelegentlich Blumen wachsen zu lassen.', - 'schwarze wolle': 'Schwarze Wolle kann gecraftet werden, indem im Craftingfeld ein Tintenbeutel neben Wolle einer beliebigen Farbe platziert wird.', - 'weizen': 'Weizen kann natürlicherweise in Dörfern gefunden oder aus Samen angebaut werden, die durch das Zerstören von Hohem Gras erhalten werden.', - 'enderperle': 'Enderperlen können zufällig durch das Töten von Endermen erhalten werden.', - 'angel': 'Eine Angel wird gecraftet, indem in einem Craftingfeld drei Stöcke in einer diagonalen Linie und dann zwei Mal Faden unter dem oberen rechten Stöck platziert werden.', - 'knochenmehl': 'Knochenmehl kann gecraftet werden, indem ein Knochen in einem Craftingfeld platziert wird.', - 'quarz': 'Netzerquarz kann erhalten werden, indem Netzquarzerz in einem Ofen geschmolzen wird.', - 'schwarzeichenholzbrett': 'Schwarzeichenholzbretter können erhalten werden, indem Schwarzeichenholz in einer Werkbank platziert wird.', - 'antriebsschiene': 'Eine Antriebsschiene kann gecraftet werden, indem ein Stock im Feld ganz in der Mitte, Redstone im unteren mittleren Feld und Goldbarren in den Feldern der rechten und linken Spalte platziert werden.', - 'leuchtfeuer': 'Ein Leuchtfeuer kann gecraftet werden, indem in einer Werkbank ein Netherstern ganz in der Mitte, drei Obsidiane in den Feldern der untersten Reihe und fünf Mal Glas in den verbleibenden Feldern platziert werden.', - 'blau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'schwarzeichenholztür': 'Eine Schwarzeichenholztür kann gecraftet werden, indem sechs Schwarzeichenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'eisengolem': 'Ein Eisengolem kann ähnlich wie ein Schneegolem erschaffen werden, indem ein Kürbiskopf auf zwei Eisenblöcken platziert wird. Danach muss links und rechts des Eisenblocks ganz in der Mitte jeweils ein Eisenblock platziert werden.', - 'fichtenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'rosa wolle': 'Rosa Wolle kann gecraftet werden, indem im Craftingfeld Rosa Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'feuerkugel': 'Eine Feuerkugel kann gecraftet werden, indem in der Werkbank Lohenstaub im mittleren linken Feld, Kohle im Feld ganz in der Mitte und Schwarzpulver im unteren mittleren Feld platziert wird.', - 'akazienholztür': 'Eine Akazienholztür kann gecraftet werden, indem sechs Akazienholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'schallplatte chirp': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'eichenlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'pfeil': 'Ein Pfeil kann gecraftet werden, indem in der Werkbank ein Feuerstein in das obere mittlere Feld, ein Stock in das Feld ganz in der Mitte und eine Feder in das untere mittlere Feld gelegt werden.', - 'holzaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'glasscheibe': 'Eine Glasscheibe kann gecraftet werden, indem sechs Glasblöcke in die beiden unteren Reihen einer Werkbank platziert werden.', - 'endertruhe': 'Eine Endertruhe kann gecraftet werden, indem in einer Werkbank ein Enderauge im Feld ganz in der Mitte platziert und von acht Obsidian-Blöcken umgeben wird.', - 'hellblaue wolle': 'Hellblaue Wolle kann gecraftet werden, indem in einem Craftingfeld Hellblauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'faden': 'Faden kann zufällig durch das Töten von Spinnen oder das Zerstören von Spinnennetzen erhalten werden.', - 'rote sandsteintreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'violette wolle': 'Violette Wolle kann gecraftet werden, indem im Craftingfeld Violetter Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'schwarz gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'verzaubertes buch': 'Verzauberte Bücher können in den Truhen der Verliese, Festungen, Wüsten- und Dschungeltempel und Minen gefunden werden.', - 'knopf': 'Ein Knopf kann gecraftet werden, indem ein einziger glatter Stein oder ein einziges Holzbrett in einem Craftingfeld platziert wird.', - 'hellgrüne wolle': 'Hellgrüne Wolle kann gecraftet werden, indem im Craftingfeld Hellgrüner Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'grobe erde': 'Grobe Erde kann erhalten werden, indem Erde aus Riesentaiga-, Tafelberg- oder Savanne-Biomen zerbrochen wird.', - 'ghastträne': 'Ghasttränen können selten durch das Töten von Ghasts erhalten werden.', - 'seelensand': 'Seelensand kann gewöhnlich in der gesamten Nether-Dimension gefunden werden.', - 'brauner pilz': 'Braune Pilze können natürlich in schlecht beleuchteten Bereichen, Pilzbiomen oder im Nether gefunden werden.', - 'kettenhaube': 'Eine Kettenrüstung kann durch den Handel mit einem Dorfbewohner oder einen seltenen Drop von einer Kreatur erhalten werden.', - 'beschriebenes buch': 'Ein Beschriebenes Buch entsteht, wenn ein Buch und Feder signiert wird.', - 'fichtensetzling': 'Fichtensetzlinge können zufällig erhalten werden, indem Fichtennadeln zerstört werden.', - 'eichensetzling': 'Eichensetzlinge können zufällig erhalten werden, indem Eichenlaub zerstört wird.', - 'nachtlichtsensor': 'Durch einen Rechtsklick auf einen Tageslichtsensor kann dieser in einen Nachtlichtsensor umgewandelt werden.', - 'sandsteintreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'redstone-lampe': 'Eine Redstone-Lampe wird hergestellt, indem ein Glowstone in einer Werkbank im mittleren Feld platziert und von vier Redstones umgeben wird.', - 'glowstone': 'Glowstone kann auf den Decken in der Nether-Dimension gefunden werden.', - 'holzdruckplatte': 'Eine Holzdruckplatte lässt sich craften, indem zwei Holzbretter horizontal nebeneinander in das Craftingfeld gelegt werden.', - 'holzkohle': 'Holzkohle wird erhalten, indem Holzblöcke in einem Ofen geschmolzen werden.', - 'kettenstiefel': 'Eine Kettenrüstung kann durch den Handel mit einem Dorfbewohner oder einen seltenen Drop von einer Kreatur erhalten werden.', - 'leiter': 'Eine Leiter kann gecraftet werden, indem Stöcke in alle Felder einer Werkbank mit Ausnahme des Feldes ganz in der Mitte und des unteren mittleren Feldes platziert werden.', - 'bemooster bruchstein': 'Bemooster Bruchstein oder früher Moosstein kann gecraftet werden, indem Ranken in einer Werkbank im Feld neben einem Bruchstein platziert werden. Er kann auch natürlicherweise in verschiedenen Verliesen gefunden werden.', - 'goldspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'akazienholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'birkenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'schallplatte ward': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'schallplatte': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'verzauberter goldener apfel': 'Ein verzauberter Goldener Apfel kann gecraftet werden, indem ein Apfel in das Feld ganz in der Mitte gelegt und dann von acht Goldblöcken umgeben wird.', - 'weißer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'eisenschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'gemeißelter roter sandstein': 'Gemeißelter roter Sandstein kann gecraftet werden, indem im Craftingfeld eine rote Sandsteinstufe über einer anderen roten Sandsteinstufe platziert wird.', - 'steinziegeltreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'sruckplatte': 'Eine Druckplatte lässt sich craften, indem entweder zwei glatte Steine oder zwei Holzbretter horizontal nebeneinander in das Craftingfeld gelegt werden.', - 'tropenholzbrett': 'Tropenholzbretter können erhalten werden, indem Tropenholz in einer Werkbank platziert wird.', - 'grüne wolle': 'Grüne Wolle kann gecraftet werden, indem im Craftingfeld Kaktusgrün neben Wolle einer beliebigen Farbe platziert wird.', - 'bogen': 'Ein Bogen kann gecraftet werden, indem in einer Werkbank drei Mal Faden in den Feldern der rechten Spalte und dann drei Stöcke in Form eines Kleinerzeichens neben den Fäden platziert werden.', - 'hellgrüner teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'feuerstein': 'Flint droppt zufällig beim Zerbrechen von Kies.', - 'schwarz gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - }, -}; diff --git a/examples/apps/alexa-skill-kit-sdk-howtoskill/template.yaml b/examples/apps/alexa-skill-kit-sdk-howtoskill/template.yaml deleted file mode 100644 index 7021ed1cd1..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-howtoskill/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrate a basic How-to skill built with the ASK NodeJS SDK -Parameters: - TopicNameParameter: - Type: String -Resources: - alexaskillkitsdkhowtoskill: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Demonstrate a basic How-to skill built with the ASK NodeJS SDK - MemorySize: 128 - Timeout: 7 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter diff --git a/examples/apps/alexa-skill-kit-sdk-triviaskill/index.js b/examples/apps/alexa-skill-kit-sdk-triviaskill/index.js deleted file mode 100644 index d40ff3d371..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-triviaskill/index.js +++ /dev/null @@ -1,371 +0,0 @@ -/* eslint-disable func-names */ -/* eslint-disable dot-notation */ -/* eslint-disable new-cap */ -/* eslint quote-props: ['error', 'consistent']*/ -/** - * This sample demonstrates a simple skill built with the Amazon Alexa Skills - * nodejs skill development kit. - * This sample supports en-US lauguage. - * The Intent Schema, Custom Slots and Sample Utterances for this skill, as well - * as testing instructions are located at https://github.com/alexa/skill-sample-nodejs-trivia - **/ - -'use strict'; - -const Alexa = require('alexa-sdk'); -const questions = require('./question'); - -const ANSWER_COUNT = 4; // The number of possible answers per trivia question. -const GAME_LENGTH = 5; // The number of questions per trivia game. -const GAME_STATES = { - TRIVIA: '_TRIVIAMODE', // Asking trivia questions. - START: '_STARTMODE', // Entry point, start the game. - HELP: '_HELPMODE', // The user is asking for help. -}; -const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL) - -/** - * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods. - * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in. - */ -const languageString = { - 'en': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_EN_US'], - 'GAME_NAME': 'Reindeer Trivia', // Be sure to change this for your skill. - 'HELP_MESSAGE': 'I will ask you %s multiple choice questions. Respond with the number of the answer. ' + - 'For example, say one, two, three, or four. To start a new game at any time, say, start game. ', - 'REPEAT_QUESTION_MESSAGE': 'To repeat the last question, say, repeat. ', - 'ASK_MESSAGE_START': 'Would you like to start playing?', - 'HELP_REPROMPT': 'To give an answer to a question, respond with the number of the answer. ', - 'STOP_MESSAGE': 'Would you like to keep playing?', - 'CANCEL_MESSAGE': 'Ok, let\'s play again soon.', - 'NO_MESSAGE': 'Ok, we\'ll play another time. Goodbye!', - 'TRIVIA_UNHANDLED': 'Try saying a number between 1 and %s', - 'HELP_UNHANDLED': 'Say yes to continue, or no to end the game.', - 'START_UNHANDLED': 'Say start to start a new game.', - 'NEW_GAME_MESSAGE': 'Welcome to %s. ', - 'WELCOME_MESSAGE': 'I will ask you %s questions, try to get as many right as you can. ' + - 'Just say the number of the answer. Let\'s begin. ', - 'ANSWER_CORRECT_MESSAGE': 'correct. ', - 'ANSWER_WRONG_MESSAGE': 'wrong. ', - 'CORRECT_ANSWER_MESSAGE': 'The correct answer is %s: %s. ', - 'ANSWER_IS_MESSAGE': 'That answer is ', - 'TELL_QUESTION_MESSAGE': 'Question %s. %s ', - 'GAME_OVER_MESSAGE': 'You got %s out of %s questions correct. Thank you for playing!', - 'SCORE_IS_MESSAGE': 'Your score is %s. ', - }, - }, - 'en-US': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_EN_US'], - 'GAME_NAME': 'American Reindeer Trivia', // Be sure to change this for your skill. - }, - }, - 'en-GB': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_EN_GB'], - 'GAME_NAME': 'British Reindeer Trivia', // Be sure to change this for your skill. - }, - }, - 'de': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_DE_DE'], - 'GAME_NAME': 'Wissenswertes über Rentiere in Deutsch', // Be sure to change this for your skill. - 'HELP_MESSAGE': 'Ich stelle dir %s Multiple-Choice-Fragen. Antworte mit der Zahl, die zur richtigen Antwort gehört. ' + - 'Sage beispielsweise eins, zwei, drei oder vier. Du kannst jederzeit ein neues Spiel beginnen, sage einfach „Spiel starten“. ', - 'REPEAT_QUESTION_MESSAGE': 'Wenn die letzte Frage wiederholt werden soll, sage „Wiederholen“ ', - 'ASK_MESSAGE_START': 'Möchten Sie beginnen?', - 'HELP_REPROMPT': 'Wenn du eine Frage beantworten willst, antworte mit der Zahl, die zur richtigen Antwort gehört. ', - 'STOP_MESSAGE': 'Möchtest du weiterspielen?', - 'CANCEL_MESSAGE': 'OK, dann lass uns bald mal wieder spielen.', - 'NO_MESSAGE': 'OK, spielen wir ein andermal. Auf Wiedersehen!', - 'TRIVIA_UNHANDLED': 'Sagt eine Zahl beispielsweise zwischen 1 und %s', - 'HELP_UNHANDLED': 'Sage ja, um fortzufahren, oder nein, um das Spiel zu beenden.', - 'START_UNHANDLED': 'Du kannst jederzeit ein neues Spiel beginnen, sage einfach „Spiel starten“.', - 'NEW_GAME_MESSAGE': 'Willkommen bei %s. ', - 'WELCOME_MESSAGE': 'Ich stelle dir %s Fragen und du versuchst, so viele wie möglich richtig zu beantworten. ' + - 'Sage einfach die Zahl, die zur richtigen Antwort passt. Fangen wir an. ', - 'ANSWER_CORRECT_MESSAGE': 'Richtig. ', - 'ANSWER_WRONG_MESSAGE': 'Falsch. ', - 'CORRECT_ANSWER_MESSAGE': 'Die richtige Antwort ist %s: %s. ', - 'ANSWER_IS_MESSAGE': 'Diese Antwort ist ', - 'TELL_QUESTION_MESSAGE': 'Frage %s. %s ', - 'GAME_OVER_MESSAGE': 'Du hast %s von %s richtig beantwortet. Danke fürs Mitspielen!', - 'SCORE_IS_MESSAGE': 'Dein Ergebnis ist %s. ', - }, - }, -}; - -const newSessionHandlers = { - 'LaunchRequest': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', true); - }, - 'AMAZON.StartOverIntent': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', true); - }, - 'AMAZON.HelpIntent': function () { - this.handler.state = GAME_STATES.HELP; - this.emitWithState('helpTheUser', true); - }, - 'Unhandled': function () { - const speechOutput = this.t('START_UNHANDLED'); - this.emit(':ask', speechOutput, speechOutput); - }, -}; - -function populateGameQuestions(translatedQuestions) { - const gameQuestions = []; - const indexList = []; - let index = translatedQuestions.length; - - if (GAME_LENGTH > index) { - throw new Error('Invalid Game Length.'); - } - - for (let i = 0; i < translatedQuestions.length; i++) { - indexList.push(i); - } - - // Pick GAME_LENGTH random questions from the list to ask the user, make sure there are no repeats. - for (let j = 0; j < GAME_LENGTH; j++) { - const rand = Math.floor(Math.random() * index); - index -= 1; - - const temp = indexList[index]; - indexList[index] = indexList[rand]; - indexList[rand] = temp; - gameQuestions.push(indexList[index]); - } - - return gameQuestions; -} - -/** - * Get the answers for a given question, and place the correct answer at the spot marked by the - * correctAnswerTargetLocation variable. Note that you can have as many answers as you want but - * only ANSWER_COUNT will be selected. - * */ -function populateRoundAnswers(gameQuestionIndexes, correctAnswerIndex, correctAnswerTargetLocation, translatedQuestions) { - const answers = []; - const answersCopy = translatedQuestions[gameQuestionIndexes[correctAnswerIndex]][Object.keys(translatedQuestions[gameQuestionIndexes[correctAnswerIndex]])[0]].slice(); - let index = answersCopy.length; - - if (index < ANSWER_COUNT) { - throw new Error('Not enough answers for question.'); - } - - // Shuffle the answers, excluding the first element which is the correct answer. - for (let j = 1; j < answersCopy.length; j++) { - const rand = Math.floor(Math.random() * (index - 1)) + 1; - index -= 1; - - const swapTemp1 = answersCopy[index]; - answersCopy[index] = answersCopy[rand]; - answersCopy[rand] = swapTemp1; - } - - // Swap the correct answer into the target location - for (let i = 0; i < ANSWER_COUNT; i++) { - answers[i] = answersCopy[i]; - } - const swapTemp2 = answers[0]; - answers[0] = answers[correctAnswerTargetLocation]; - answers[correctAnswerTargetLocation] = swapTemp2; - return answers; -} - -function isAnswerSlotValid(intent) { - const answerSlotFilled = intent && intent.slots && intent.slots.Answer && intent.slots.Answer.value; - const answerSlotIsInt = answerSlotFilled && !isNaN(parseInt(intent.slots.Answer.value, 10)); - return answerSlotIsInt - && parseInt(intent.slots.Answer.value, 10) < (ANSWER_COUNT + 1) - && parseInt(intent.slots.Answer.value, 10) > 0; -} - -function handleUserGuess(userGaveUp) { - const answerSlotValid = isAnswerSlotValid(this.event.request.intent); - let speechOutput = ''; - let speechOutputAnalysis = ''; - const gameQuestions = this.attributes.questions; - let correctAnswerIndex = parseInt(this.attributes.correctAnswerIndex, 10); - let currentScore = parseInt(this.attributes.score, 10); - let currentQuestionIndex = parseInt(this.attributes.currentQuestionIndex, 10); - const correctAnswerText = this.attributes.correctAnswerText; - const translatedQuestions = this.t('QUESTIONS'); - - if (answerSlotValid && parseInt(this.event.request.intent.slots.Answer.value, 10) === this.attributes['correctAnswerIndex']) { - currentScore++; - speechOutputAnalysis = this.t('ANSWER_CORRECT_MESSAGE'); - } else { - if (!userGaveUp) { - speechOutputAnalysis = this.t('ANSWER_WRONG_MESSAGE'); - } - - speechOutputAnalysis += this.t('CORRECT_ANSWER_MESSAGE', correctAnswerIndex, correctAnswerText); - } - - // Check if we can exit the game session after GAME_LENGTH questions (zero-indexed) - if (this.attributes['currentQuestionIndex'] === GAME_LENGTH - 1) { - speechOutput = userGaveUp ? '' : this.t('ANSWER_IS_MESSAGE'); - speechOutput += speechOutputAnalysis + this.t('GAME_OVER_MESSAGE', currentScore.toString(), GAME_LENGTH.toString()); - - this.emit(':tell', speechOutput); - } else { - currentQuestionIndex += 1; - correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)); - const spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]; - const roundAnswers = populateRoundAnswers.call(this, gameQuestions, currentQuestionIndex, correctAnswerIndex, translatedQuestions); - const questionIndexForSpeech = currentQuestionIndex + 1; - let repromptText = this.t('TELL_QUESTION_MESSAGE', questionIndexForSpeech.toString(), spokenQuestion); - - for (let i = 0; i < ANSWER_COUNT; i++) { - repromptText += `${i + 1}. ${roundAnswers[i]}. `; - } - - speechOutput += userGaveUp ? '' : this.t('ANSWER_IS_MESSAGE'); - speechOutput += speechOutputAnalysis + this.t('SCORE_IS_MESSAGE', currentScore.toString()) + repromptText; - - Object.assign(this.attributes, { - 'speechOutput': repromptText, - 'repromptText': repromptText, - 'currentQuestionIndex': currentQuestionIndex, - 'correctAnswerIndex': correctAnswerIndex + 1, - 'questions': gameQuestions, - 'score': currentScore, - 'correctAnswerText': translatedQuestions[gameQuestions[currentQuestionIndex]][Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]][0], - }); - - this.emit(':askWithCard', speechOutput, repromptText, this.t('GAME_NAME'), repromptText); - } -} - -const startStateHandlers = Alexa.CreateStateHandler(GAME_STATES.START, { - 'StartGame': function (newGame) { - let speechOutput = newGame ? this.t('NEW_GAME_MESSAGE', this.t('GAME_NAME')) + this.t('WELCOME_MESSAGE', GAME_LENGTH.toString()) : ''; - // Select GAME_LENGTH questions for the game - const translatedQuestions = this.t('QUESTIONS'); - const gameQuestions = populateGameQuestions(translatedQuestions); - // Generate a random index for the correct answer, from 0 to 3 - const correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)); - // Select and shuffle the answers for each question - const roundAnswers = populateRoundAnswers(gameQuestions, 0, correctAnswerIndex, translatedQuestions); - const currentQuestionIndex = 0; - const spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]; - let repromptText = this.t('TELL_QUESTION_MESSAGE', '1', spokenQuestion); - - for (let i = 0; i < ANSWER_COUNT; i++) { - repromptText += `${i + 1}. ${roundAnswers[i]}. `; - } - - speechOutput += repromptText; - - Object.assign(this.attributes, { - 'speechOutput': repromptText, - 'repromptText': repromptText, - 'currentQuestionIndex': currentQuestionIndex, - 'correctAnswerIndex': correctAnswerIndex + 1, - 'questions': gameQuestions, - 'score': 0, - 'correctAnswerText': translatedQuestions[gameQuestions[currentQuestionIndex]][Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]][0], - }); - - // Set the current state to trivia mode. The skill will now use handlers defined in triviaStateHandlers - this.handler.state = GAME_STATES.TRIVIA; - this.emit(':askWithCard', speechOutput, repromptText, this.t('GAME_NAME'), repromptText); - }, -}); - -const triviaStateHandlers = Alexa.CreateStateHandler(GAME_STATES.TRIVIA, { - 'AnswerIntent': function () { - handleUserGuess.call(this, false); - }, - 'DontKnowIntent': function () { - handleUserGuess.call(this, true); - }, - 'AMAZON.StartOverIntent': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', false); - }, - 'AMAZON.RepeatIntent': function () { - this.emit(':ask', this.attributes['speechOutput'], this.attributes['repromptText']); - }, - 'AMAZON.HelpIntent': function () { - this.handler.state = GAME_STATES.HELP; - this.emitWithState('helpTheUser', false); - }, - 'AMAZON.StopIntent': function () { - this.handler.state = GAME_STATES.HELP; - const speechOutput = this.t('STOP_MESSAGE'); - this.emit(':ask', speechOutput, speechOutput); - }, - 'AMAZON.CancelIntent': function () { - this.emit(':tell', this.t('CANCEL_MESSAGE')); - }, - 'Unhandled': function () { - const speechOutput = this.t('TRIVIA_UNHANDLED', ANSWER_COUNT.toString()); - this.emit(':ask', speechOutput, speechOutput); - }, - 'SessionEndedRequest': function () { - console.log(`Session ended in trivia state: ${this.event.request.reason}`); - }, -}); - -const helpStateHandlers = Alexa.CreateStateHandler(GAME_STATES.HELP, { - 'helpTheUser': function (newGame) { - const askMessage = newGame ? this.t('ASK_MESSAGE_START') : this.t('REPEAT_QUESTION_MESSAGE') + this.t('STOP_MESSAGE'); - const speechOutput = this.t('HELP_MESSAGE', GAME_LENGTH) + askMessage; - const repromptText = this.t('HELP_REPROMPT') + askMessage; - this.emit(':ask', speechOutput, repromptText); - }, - 'AMAZON.StartOverIntent': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', false); - }, - 'AMAZON.RepeatIntent': function () { - const newGame = !(this.attributes['speechOutput'] && this.attributes['repromptText']); - this.emitWithState('helpTheUser', newGame); - }, - 'AMAZON.HelpIntent': function () { - const newGame = !(this.attributes['speechOutput'] && this.attributes['repromptText']); - this.emitWithState('helpTheUser', newGame); - }, - 'AMAZON.YesIntent': function () { - if (this.attributes['speechOutput'] && this.attributes['repromptText']) { - this.handler.state = GAME_STATES.TRIVIA; - this.emitWithState('AMAZON.RepeatIntent'); - } else { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', false); - } - }, - 'AMAZON.NoIntent': function () { - const speechOutput = this.t('NO_MESSAGE'); - this.emit(':tell', speechOutput); - }, - 'AMAZON.StopIntent': function () { - const speechOutput = this.t('STOP_MESSAGE'); - this.emit(':ask', speechOutput, speechOutput); - }, - 'AMAZON.CancelIntent': function () { - this.emit(':tell', this.t('CANCEL_MESSAGE')); - }, - 'Unhandled': function () { - const speechOutput = this.t('HELP_UNHANDLED'); - this.emit(':ask', speechOutput, speechOutput); - }, - 'SessionEndedRequest': function () { - console.log(`Session ended in help state: ${this.event.request.reason}`); - }, -}); - -exports.handler = function (event, context) { - const alexa = Alexa.handler(event, context); - alexa.appId = APP_ID; - // To enable string internationalization (i18n) features, set a resources object. - alexa.resources = languageString; - alexa.registerHandlers(newSessionHandlers, startStateHandlers, triviaStateHandlers, helpStateHandlers); - alexa.execute(); -}; diff --git a/examples/apps/alexa-skill-kit-sdk-triviaskill/package.json b/examples/apps/alexa-skill-kit-sdk-triviaskill/package.json deleted file mode 100644 index 6c42250a21..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-triviaskill/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "alexa-skill-kit-sdk-triviaskill", - "version": "1.0.0", - "private": true, - "dependencies": { - "alexa-sdk": "^1.0.10" - } -} diff --git a/examples/apps/alexa-skill-kit-sdk-triviaskill/question.js b/examples/apps/alexa-skill-kit-sdk-triviaskill/question.js deleted file mode 100644 index 152919b7fd..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-triviaskill/question.js +++ /dev/null @@ -1,755 +0,0 @@ -'use strict'; - -module.exports = { - /** - * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods. - * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in. - */ - QUESTIONS_EN_GB: [ - { - 'Reindeer have very thick coats, how many hairs per square inch do they have?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'The 1964 classic Rudolph The Red Nosed Reindeer was filmed in. ': [ - 'Japan', - 'United States', - 'Finland', - 'Germany', - 'Canada', - 'Norway', - 'France', - ], - }, - { - 'Santas reindeer are cared for by one of the Christmas elves, what is his name?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pepper Minstix', - ], - }, - { - 'If all of Santas reindeer had antlers while pulling his Christmas sleigh, they would all be. ': [ - 'Girls', - 'Boys', - 'Girls and boys', - 'No way to tell', - ], - }, - { - 'What do Reindeer eat?': [ - 'Lichen', - 'Grasses', - 'Leaves', - 'Berries', - ], - }, - { - 'What of the following is not true?': [ - 'Caribou live on all continents', - 'Both reindeer and Caribou are the same species', - 'Caribou are bigger than reindeer', - 'Reindeer live in Scandinavia and Russia', - ], - }, - { - 'In what year did Rudolph make his television debut?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Who was the voice of Rudolph in the 1964 classic?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'In 1939 what retailer used the story of Rudolph the Red Nose Reindeer?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Santa\'s reindeer named Donner was originally named what?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Who invented the story of Rudolph?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'In what location will you not find reindeer?': [ - 'North Pole', - 'Lapland', - 'Korvatunturi mountain', - 'Finland', - ], - }, - { - 'What Makes Santa\'s Reindeer Fly?': [ - 'Magical Reindeer Dust', - 'Fusion', - 'Amanita muscaria', - 'Elves', - ], - }, - { - 'Including Rudolph, how many reindeer hooves are there?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Santa only has one female reindeer. Which one is it?': [ - 'Vixen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'In the 1964 classic Rudolph The Red Nosed Reindeer, what was the snowman narrators name?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'What was Rudolph\'s father\'s name?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'In the 1964 movie, What was the name of the coach of the Reindeer Games?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'In the 1964 movie, what is the name of the deer that Rudolph befriends at the reindeer games?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'In the 1964 movie, How did Donner, Rudolph\'s father, try to hide Rudolph\'s nose?': [ - 'Black mud', - 'Bag', - 'Pillow case', - 'Sock', - ], - }, - { - 'In the 1964 movie, what does the Misfit Elf want to be instead of a Santa Elf?': [ - 'Dentist', - 'Reindeer', - 'Toy maker', - 'Candlestick maker', - ], - }, - { - 'In the 1964 movie,what was the Bumble\'s one weakness?': [ - 'Could not swim', - 'Always hungry', - 'Candy canes', - 'Cross eyed', - ], - }, - { - 'In the 1964 movie, what is Yukon Cornelius really in search of?': [ - 'Peppermint', - 'Gold', - 'India', - 'Polar Bears', - ], - }, - { - 'In the 1964 movie, why is the train on the Island of Misfit Toys?': [ - 'Square wheels', - 'No Engine', - 'Paint does not match', - 'It does not toot', - ], - }, - { - 'In the 1964 movie, what is the name of the Jack in the Box?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'In the 1964 movie, why did Santa Claus almost cancel Christmas?': [ - 'Storm', - 'No snow', - 'No toys', - 'The Reindeer were sick', - ], - }, - { - 'In the 1964 movie, what animal noise did the elf make to distract the Bumble?': [ - 'Oink', - 'Growl', - 'Bark', - 'Meow', - ], - }, - { - 'In the 1964 movie, what is the name of the prospector?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'How far do reindeer travel when they migrate?': [ - '3000 miles', - '700 miles', - '500 miles', - '0 miles', - ], - }, - { - 'How fast can a reindeer run?': [ - '48 miles per hour', - '17 miles per hour', - '19 miles per hour', - '14 miles per hour', - '52 miles per hour', - '41 miles per hour', - ], - }, - ], - QUESTIONS_EN_US: [ - { - 'Reindeer have very thick coats, how many hairs per square inch do they have?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'The 1964 classic Rudolph The Red Nosed Reindeer was filmed in. ': [ - 'Japan', - 'United States', - 'Finland', - 'Germany', - 'Canada', - 'Norway', - 'France', - ], - }, - { - 'Santas reindeer are cared for by one of the Christmas elves, what is his name?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pepper Minstix', - ], - }, - { - 'If all of Santas reindeer had antlers while pulling his Christmas sleigh, they would all be': [ - 'Girls', - 'Boys', - 'Girls and boys', - 'No way to tell', - ], - }, - { - 'What do Reindeer eat?': [ - 'Lichen', - 'Grasses', - 'Leaves', - 'Berries', - ], - }, - { - 'What of the following is not true?': [ - 'Caribou live on all continents', - 'Both reindeer and Caribou are the same species', - 'Caribou are bigger than reindeer', - 'Reindeer live in Scandinavia and Russia', - ], - }, - { - 'In what year did Rudolph make his television debut?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Who was the voice of Rudolph in the 1964 classic?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'In 1939 what retailer used the story of Rudolph the Red Nose Reindeer?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Santa\'s reindeer named Donner was originally named what?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Who invented the story of Rudolph?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'In what location will you not find reindeer?': [ - 'North Pole', - 'Lapland', - 'Korvatunturi mountain', - 'Finland', - ], - }, - { - 'What Makes Santa\'s Reindeer Fly?': [ - 'Magical Reindeer Dust', - 'Fusion', - 'Amanita muscaria', - 'Elves', - ], - }, - { - 'Including Rudolph, how many reindeer hooves are there?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Santa only has one female reindeer. Which one is it?': [ - 'Vixen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'In the 1964 classic Rudolph The Red Nosed Reindeer, what was the snowman narrators name?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'What was Rudolph\'s father\'s name?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'In the 1964 movie, What was the name of the coach of the Reindeer Games?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'In the 1964 movie, what is the name of the deer that Rudolph befriends at the reindeer games?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'In the 1964 movie, How did Donner, Rudolph\'s father, try to hide Rudolph\'s nose?': [ - 'Black mud', - 'Bag', - 'Pillow case', - 'Sock', - ], - }, - { - 'In the 1964 movie, what does the Misfit Elf want to be instead of a Santa Elf?': [ - 'Dentist', - 'Reindeer', - 'Toy maker', - 'Candlestick maker', - ], - }, - { - 'In the 1964 movie,what was the Bumble\'s one weakness?': [ - 'Could not swim', - 'Always hungry', - 'Candy canes', - 'Cross eyed', - ], - }, - { - 'In the 1964 movie, what is Yukon Cornelius really in search of?': [ - 'Peppermint', - 'Gold', - 'India', - 'Polar Bears', - ], - }, - { - 'In the 1964 movie, why is the train on the Island of Misfit Toys?': [ - 'Square wheels', - 'No Engine', - 'Paint does not match', - 'It does not toot', - ], - }, - { - 'In the 1964 movie, what is the name of the Jack in the Box?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'In the 1964 movie, why did Santa Claus almost cancel Christmas?': [ - 'Storm', - 'No snow', - 'No toys', - 'The Reindeer were sick', - ], - }, - { - 'In the 1964 movie, what animal noise did the elf make to distract the Bumble?': [ - 'Oink', - 'Growl', - 'Bark', - 'Meow', - ], - }, - { - 'In the 1964 movie, what is the name of the prospector?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'How far do reindeer travel when they migrate?': [ - '3000 miles', - '700 miles', - '500 miles', - '0 miles', - ], - }, - { - 'How fast can a reindeer run?': [ - '48 miles per hour', - '17 miles per hour', - '19 miles per hour', - '14 miles per hour', - '52 miles per hour', - '41 miles per hour', - ], - }, - ], - QUESTIONS_DE_DE: [ - { - 'Rentiere haben ein sehr dickes Fell. Wie viele Haare pro Quadratzentimeter haben sie?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'Der Klassiker aus dem Jahr 1964, Rudolph mit der roten Nase, wurde gedreht in. ': [ - 'Japan', - 'USA', - 'Finnland', - 'Deutschland', - 'Kanada', - 'Norwegen', - 'Frankreich', - ], - }, - { - 'Um die Rentiere des Weihnachtsmanns kümmert sich eine der Weihnachtselfen. Wie heißt sie?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pfeffer Minstix', - ], - }, - { - 'Wenn alle Rentiere des Weihnachtsmanns Geweihe hätten, während sie seinen Weihnachtsschlitten ziehen, wären sie alle. ': [ - 'Weiblich', - 'Männlich', - 'Weiblich und männlich', - 'Kann man nicht sagen', - ], - }, - { - 'Was essen Rentiere?': [ - 'Flechten', - 'Gras', - 'Blätter', - 'Beeren', - ], - }, - { - 'Welche Aussage ist nicht richtig?': [ - 'Karibus leben auf allen Kontinenten', - 'Karibus und Rentiere gehören derselben Gattung an ', - 'Karibus sind größer als Rentiere', - 'Rentiere leben in Skandinavien und Russland', - ], - }, - { - 'In welchem Jahr kam Rudolph ins Fernsehen?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Wer war der Sprecher für Rudolph im klassischen Film aus dem Jahr 1964?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'Welche Handelskette verwendete 1939 die Geschichte von Rudolph mit der roten Nase?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Wie hieß das Rentier des Weihnachtsmanns namens Donner ursprünglich?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Wer hat die Geschichte von Rudolph erfunden?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'Wo findest du keine Rentiere?': [ - 'Nordpol', - 'Lappland', - 'Korvatunturi-Berge', - 'Finnland', - ], - }, - { - 'Warum können die Rentiere des Weihnachtsmanns fliegen?': [ - 'Magischer Staub der Rentiere', - 'Fusion', - 'Amanita muscaria', - 'Elfen', - ], - }, - { - 'Wieviele Rentierhufe gibt es hier einschließlich Rudolph?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Der Weihnachtsmann hat nur ein weibliches Rentier. Wie heißt es?': [ - 'Blitzen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'Wie war der Name des erzählenden Schneemanns im klassischen Film Rudolph mit der roten Nase aus dem Jahr 1964?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'Wie hieß der Vater von Rudolph?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'Wie war der Name des Trainers der Rentierspiele im klassischen Film aus dem Jahr 1964?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'Wie war im klassichen Film aus 1964 der Name des Hirsches, mit dem sich Rudolph befreundete?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'Wie hat der Vater von Rudolph, Donner, im Film aus dem Jahr 1964 versucht, die Nase von Rudolph zu verbergen?': [ - 'Schwarzer Schlamm', - 'Sack', - 'Kissenbezug', - 'Socke', - ], - }, - { - 'Was möchte die Misfit-Elfe im Film aus dem Jahr 1964 werden anstatt eine Elfe für den Weihnachtsmann?': [ - 'Zahnarzt', - 'Rentier', - 'Spielzeugmacher', - 'Kerzenmacher', - ], - }, - { - 'Was war die einzige Schwäche von Bumble im Film aus dem Jahr 1964?': [ - 'Konnte nicht schwimmen', - 'War immer hungrig', - 'Zuckerstangen', - 'Schielte', - ], - }, - { - 'Was sucht Yukon Cornelius in Wirklichkeit im Film aus dem Jahr 1964?': [ - 'Pfefferminz', - 'Gold', - 'Indien', - 'Polarbären', - ], - }, - { - 'Warum befindet sich der Zug im Film aus dem Jahr 1964 auf der Insel des fehlerhaften Spielzeugs?': [ - 'Viereckige Räder', - 'Keine Dampfmaschine', - 'Farbe stimmt nicht', - 'Pfeift nicht', - ], - }, - { - 'Wie lautet der Name des Schachtelmännchens im Film aus dem Jahr 1964?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'Warum hat der Weihnachtsmann im Film aus dem Jahr 1964 Weihnachten beinahe abgesagt?': [ - 'Sturm', - 'Kein Schnee', - 'Kein Spielzeug', - 'Die Rentiere waren krank', - ], - }, - { - 'Welches tierische Geräusch machte die Elfe im Film aus dem Jahr 1964, um den Bumble abzulenken?': [ - 'Oink', - 'Knurr', - 'Wauwau', - 'Miau', - ], - }, - { - 'Wie lautet der Name des Goldsuchers im Film aus dem Jahr 1964?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'Wie weit ziehen Rentiere auf ihren Wanderungen?': [ - '4800 km', - '1100 km', - '800 km', - '0 km', - ], - }, - { - 'Wie schnell läuft ein Rentier?': [ - '77 km pro Stunde', - '27 km pro Stunde', - '30 km pro Stunde', - '22 km pro Stunde', - '83 km pro Stunde', - '65 km pro Stunde', - ], - }, - ], -}; diff --git a/examples/apps/alexa-skill-kit-sdk-triviaskill/template.yaml b/examples/apps/alexa-skill-kit-sdk-triviaskill/template.yaml deleted file mode 100644 index 661934cd79..0000000000 --- a/examples/apps/alexa-skill-kit-sdk-triviaskill/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrate a basic trivia skill built with the ASK NodeJS SDK -Parameters: - TopicNameParameter: - Type: String -Resources: - alexaskillkitsdktriviaskill: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Demonstrate a basic trivia skill built with the ASK NodeJS SDK - MemorySize: 128 - Timeout: 7 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter \ No newline at end of file diff --git a/examples/apps/alexa-skills-kit-color-expert-python/index.js b/examples/apps/alexa-skills-kit-color-expert-python/index.js deleted file mode 100644 index d40ff3d371..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert-python/index.js +++ /dev/null @@ -1,371 +0,0 @@ -/* eslint-disable func-names */ -/* eslint-disable dot-notation */ -/* eslint-disable new-cap */ -/* eslint quote-props: ['error', 'consistent']*/ -/** - * This sample demonstrates a simple skill built with the Amazon Alexa Skills - * nodejs skill development kit. - * This sample supports en-US lauguage. - * The Intent Schema, Custom Slots and Sample Utterances for this skill, as well - * as testing instructions are located at https://github.com/alexa/skill-sample-nodejs-trivia - **/ - -'use strict'; - -const Alexa = require('alexa-sdk'); -const questions = require('./question'); - -const ANSWER_COUNT = 4; // The number of possible answers per trivia question. -const GAME_LENGTH = 5; // The number of questions per trivia game. -const GAME_STATES = { - TRIVIA: '_TRIVIAMODE', // Asking trivia questions. - START: '_STARTMODE', // Entry point, start the game. - HELP: '_HELPMODE', // The user is asking for help. -}; -const APP_ID = undefined; // TODO replace with your app ID (OPTIONAL) - -/** - * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods. - * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in. - */ -const languageString = { - 'en': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_EN_US'], - 'GAME_NAME': 'Reindeer Trivia', // Be sure to change this for your skill. - 'HELP_MESSAGE': 'I will ask you %s multiple choice questions. Respond with the number of the answer. ' + - 'For example, say one, two, three, or four. To start a new game at any time, say, start game. ', - 'REPEAT_QUESTION_MESSAGE': 'To repeat the last question, say, repeat. ', - 'ASK_MESSAGE_START': 'Would you like to start playing?', - 'HELP_REPROMPT': 'To give an answer to a question, respond with the number of the answer. ', - 'STOP_MESSAGE': 'Would you like to keep playing?', - 'CANCEL_MESSAGE': 'Ok, let\'s play again soon.', - 'NO_MESSAGE': 'Ok, we\'ll play another time. Goodbye!', - 'TRIVIA_UNHANDLED': 'Try saying a number between 1 and %s', - 'HELP_UNHANDLED': 'Say yes to continue, or no to end the game.', - 'START_UNHANDLED': 'Say start to start a new game.', - 'NEW_GAME_MESSAGE': 'Welcome to %s. ', - 'WELCOME_MESSAGE': 'I will ask you %s questions, try to get as many right as you can. ' + - 'Just say the number of the answer. Let\'s begin. ', - 'ANSWER_CORRECT_MESSAGE': 'correct. ', - 'ANSWER_WRONG_MESSAGE': 'wrong. ', - 'CORRECT_ANSWER_MESSAGE': 'The correct answer is %s: %s. ', - 'ANSWER_IS_MESSAGE': 'That answer is ', - 'TELL_QUESTION_MESSAGE': 'Question %s. %s ', - 'GAME_OVER_MESSAGE': 'You got %s out of %s questions correct. Thank you for playing!', - 'SCORE_IS_MESSAGE': 'Your score is %s. ', - }, - }, - 'en-US': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_EN_US'], - 'GAME_NAME': 'American Reindeer Trivia', // Be sure to change this for your skill. - }, - }, - 'en-GB': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_EN_GB'], - 'GAME_NAME': 'British Reindeer Trivia', // Be sure to change this for your skill. - }, - }, - 'de': { - 'translation': { - 'QUESTIONS': questions['QUESTIONS_DE_DE'], - 'GAME_NAME': 'Wissenswertes über Rentiere in Deutsch', // Be sure to change this for your skill. - 'HELP_MESSAGE': 'Ich stelle dir %s Multiple-Choice-Fragen. Antworte mit der Zahl, die zur richtigen Antwort gehört. ' + - 'Sage beispielsweise eins, zwei, drei oder vier. Du kannst jederzeit ein neues Spiel beginnen, sage einfach „Spiel starten“. ', - 'REPEAT_QUESTION_MESSAGE': 'Wenn die letzte Frage wiederholt werden soll, sage „Wiederholen“ ', - 'ASK_MESSAGE_START': 'Möchten Sie beginnen?', - 'HELP_REPROMPT': 'Wenn du eine Frage beantworten willst, antworte mit der Zahl, die zur richtigen Antwort gehört. ', - 'STOP_MESSAGE': 'Möchtest du weiterspielen?', - 'CANCEL_MESSAGE': 'OK, dann lass uns bald mal wieder spielen.', - 'NO_MESSAGE': 'OK, spielen wir ein andermal. Auf Wiedersehen!', - 'TRIVIA_UNHANDLED': 'Sagt eine Zahl beispielsweise zwischen 1 und %s', - 'HELP_UNHANDLED': 'Sage ja, um fortzufahren, oder nein, um das Spiel zu beenden.', - 'START_UNHANDLED': 'Du kannst jederzeit ein neues Spiel beginnen, sage einfach „Spiel starten“.', - 'NEW_GAME_MESSAGE': 'Willkommen bei %s. ', - 'WELCOME_MESSAGE': 'Ich stelle dir %s Fragen und du versuchst, so viele wie möglich richtig zu beantworten. ' + - 'Sage einfach die Zahl, die zur richtigen Antwort passt. Fangen wir an. ', - 'ANSWER_CORRECT_MESSAGE': 'Richtig. ', - 'ANSWER_WRONG_MESSAGE': 'Falsch. ', - 'CORRECT_ANSWER_MESSAGE': 'Die richtige Antwort ist %s: %s. ', - 'ANSWER_IS_MESSAGE': 'Diese Antwort ist ', - 'TELL_QUESTION_MESSAGE': 'Frage %s. %s ', - 'GAME_OVER_MESSAGE': 'Du hast %s von %s richtig beantwortet. Danke fürs Mitspielen!', - 'SCORE_IS_MESSAGE': 'Dein Ergebnis ist %s. ', - }, - }, -}; - -const newSessionHandlers = { - 'LaunchRequest': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', true); - }, - 'AMAZON.StartOverIntent': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', true); - }, - 'AMAZON.HelpIntent': function () { - this.handler.state = GAME_STATES.HELP; - this.emitWithState('helpTheUser', true); - }, - 'Unhandled': function () { - const speechOutput = this.t('START_UNHANDLED'); - this.emit(':ask', speechOutput, speechOutput); - }, -}; - -function populateGameQuestions(translatedQuestions) { - const gameQuestions = []; - const indexList = []; - let index = translatedQuestions.length; - - if (GAME_LENGTH > index) { - throw new Error('Invalid Game Length.'); - } - - for (let i = 0; i < translatedQuestions.length; i++) { - indexList.push(i); - } - - // Pick GAME_LENGTH random questions from the list to ask the user, make sure there are no repeats. - for (let j = 0; j < GAME_LENGTH; j++) { - const rand = Math.floor(Math.random() * index); - index -= 1; - - const temp = indexList[index]; - indexList[index] = indexList[rand]; - indexList[rand] = temp; - gameQuestions.push(indexList[index]); - } - - return gameQuestions; -} - -/** - * Get the answers for a given question, and place the correct answer at the spot marked by the - * correctAnswerTargetLocation variable. Note that you can have as many answers as you want but - * only ANSWER_COUNT will be selected. - * */ -function populateRoundAnswers(gameQuestionIndexes, correctAnswerIndex, correctAnswerTargetLocation, translatedQuestions) { - const answers = []; - const answersCopy = translatedQuestions[gameQuestionIndexes[correctAnswerIndex]][Object.keys(translatedQuestions[gameQuestionIndexes[correctAnswerIndex]])[0]].slice(); - let index = answersCopy.length; - - if (index < ANSWER_COUNT) { - throw new Error('Not enough answers for question.'); - } - - // Shuffle the answers, excluding the first element which is the correct answer. - for (let j = 1; j < answersCopy.length; j++) { - const rand = Math.floor(Math.random() * (index - 1)) + 1; - index -= 1; - - const swapTemp1 = answersCopy[index]; - answersCopy[index] = answersCopy[rand]; - answersCopy[rand] = swapTemp1; - } - - // Swap the correct answer into the target location - for (let i = 0; i < ANSWER_COUNT; i++) { - answers[i] = answersCopy[i]; - } - const swapTemp2 = answers[0]; - answers[0] = answers[correctAnswerTargetLocation]; - answers[correctAnswerTargetLocation] = swapTemp2; - return answers; -} - -function isAnswerSlotValid(intent) { - const answerSlotFilled = intent && intent.slots && intent.slots.Answer && intent.slots.Answer.value; - const answerSlotIsInt = answerSlotFilled && !isNaN(parseInt(intent.slots.Answer.value, 10)); - return answerSlotIsInt - && parseInt(intent.slots.Answer.value, 10) < (ANSWER_COUNT + 1) - && parseInt(intent.slots.Answer.value, 10) > 0; -} - -function handleUserGuess(userGaveUp) { - const answerSlotValid = isAnswerSlotValid(this.event.request.intent); - let speechOutput = ''; - let speechOutputAnalysis = ''; - const gameQuestions = this.attributes.questions; - let correctAnswerIndex = parseInt(this.attributes.correctAnswerIndex, 10); - let currentScore = parseInt(this.attributes.score, 10); - let currentQuestionIndex = parseInt(this.attributes.currentQuestionIndex, 10); - const correctAnswerText = this.attributes.correctAnswerText; - const translatedQuestions = this.t('QUESTIONS'); - - if (answerSlotValid && parseInt(this.event.request.intent.slots.Answer.value, 10) === this.attributes['correctAnswerIndex']) { - currentScore++; - speechOutputAnalysis = this.t('ANSWER_CORRECT_MESSAGE'); - } else { - if (!userGaveUp) { - speechOutputAnalysis = this.t('ANSWER_WRONG_MESSAGE'); - } - - speechOutputAnalysis += this.t('CORRECT_ANSWER_MESSAGE', correctAnswerIndex, correctAnswerText); - } - - // Check if we can exit the game session after GAME_LENGTH questions (zero-indexed) - if (this.attributes['currentQuestionIndex'] === GAME_LENGTH - 1) { - speechOutput = userGaveUp ? '' : this.t('ANSWER_IS_MESSAGE'); - speechOutput += speechOutputAnalysis + this.t('GAME_OVER_MESSAGE', currentScore.toString(), GAME_LENGTH.toString()); - - this.emit(':tell', speechOutput); - } else { - currentQuestionIndex += 1; - correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)); - const spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]; - const roundAnswers = populateRoundAnswers.call(this, gameQuestions, currentQuestionIndex, correctAnswerIndex, translatedQuestions); - const questionIndexForSpeech = currentQuestionIndex + 1; - let repromptText = this.t('TELL_QUESTION_MESSAGE', questionIndexForSpeech.toString(), spokenQuestion); - - for (let i = 0; i < ANSWER_COUNT; i++) { - repromptText += `${i + 1}. ${roundAnswers[i]}. `; - } - - speechOutput += userGaveUp ? '' : this.t('ANSWER_IS_MESSAGE'); - speechOutput += speechOutputAnalysis + this.t('SCORE_IS_MESSAGE', currentScore.toString()) + repromptText; - - Object.assign(this.attributes, { - 'speechOutput': repromptText, - 'repromptText': repromptText, - 'currentQuestionIndex': currentQuestionIndex, - 'correctAnswerIndex': correctAnswerIndex + 1, - 'questions': gameQuestions, - 'score': currentScore, - 'correctAnswerText': translatedQuestions[gameQuestions[currentQuestionIndex]][Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]][0], - }); - - this.emit(':askWithCard', speechOutput, repromptText, this.t('GAME_NAME'), repromptText); - } -} - -const startStateHandlers = Alexa.CreateStateHandler(GAME_STATES.START, { - 'StartGame': function (newGame) { - let speechOutput = newGame ? this.t('NEW_GAME_MESSAGE', this.t('GAME_NAME')) + this.t('WELCOME_MESSAGE', GAME_LENGTH.toString()) : ''; - // Select GAME_LENGTH questions for the game - const translatedQuestions = this.t('QUESTIONS'); - const gameQuestions = populateGameQuestions(translatedQuestions); - // Generate a random index for the correct answer, from 0 to 3 - const correctAnswerIndex = Math.floor(Math.random() * (ANSWER_COUNT)); - // Select and shuffle the answers for each question - const roundAnswers = populateRoundAnswers(gameQuestions, 0, correctAnswerIndex, translatedQuestions); - const currentQuestionIndex = 0; - const spokenQuestion = Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]; - let repromptText = this.t('TELL_QUESTION_MESSAGE', '1', spokenQuestion); - - for (let i = 0; i < ANSWER_COUNT; i++) { - repromptText += `${i + 1}. ${roundAnswers[i]}. `; - } - - speechOutput += repromptText; - - Object.assign(this.attributes, { - 'speechOutput': repromptText, - 'repromptText': repromptText, - 'currentQuestionIndex': currentQuestionIndex, - 'correctAnswerIndex': correctAnswerIndex + 1, - 'questions': gameQuestions, - 'score': 0, - 'correctAnswerText': translatedQuestions[gameQuestions[currentQuestionIndex]][Object.keys(translatedQuestions[gameQuestions[currentQuestionIndex]])[0]][0], - }); - - // Set the current state to trivia mode. The skill will now use handlers defined in triviaStateHandlers - this.handler.state = GAME_STATES.TRIVIA; - this.emit(':askWithCard', speechOutput, repromptText, this.t('GAME_NAME'), repromptText); - }, -}); - -const triviaStateHandlers = Alexa.CreateStateHandler(GAME_STATES.TRIVIA, { - 'AnswerIntent': function () { - handleUserGuess.call(this, false); - }, - 'DontKnowIntent': function () { - handleUserGuess.call(this, true); - }, - 'AMAZON.StartOverIntent': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', false); - }, - 'AMAZON.RepeatIntent': function () { - this.emit(':ask', this.attributes['speechOutput'], this.attributes['repromptText']); - }, - 'AMAZON.HelpIntent': function () { - this.handler.state = GAME_STATES.HELP; - this.emitWithState('helpTheUser', false); - }, - 'AMAZON.StopIntent': function () { - this.handler.state = GAME_STATES.HELP; - const speechOutput = this.t('STOP_MESSAGE'); - this.emit(':ask', speechOutput, speechOutput); - }, - 'AMAZON.CancelIntent': function () { - this.emit(':tell', this.t('CANCEL_MESSAGE')); - }, - 'Unhandled': function () { - const speechOutput = this.t('TRIVIA_UNHANDLED', ANSWER_COUNT.toString()); - this.emit(':ask', speechOutput, speechOutput); - }, - 'SessionEndedRequest': function () { - console.log(`Session ended in trivia state: ${this.event.request.reason}`); - }, -}); - -const helpStateHandlers = Alexa.CreateStateHandler(GAME_STATES.HELP, { - 'helpTheUser': function (newGame) { - const askMessage = newGame ? this.t('ASK_MESSAGE_START') : this.t('REPEAT_QUESTION_MESSAGE') + this.t('STOP_MESSAGE'); - const speechOutput = this.t('HELP_MESSAGE', GAME_LENGTH) + askMessage; - const repromptText = this.t('HELP_REPROMPT') + askMessage; - this.emit(':ask', speechOutput, repromptText); - }, - 'AMAZON.StartOverIntent': function () { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', false); - }, - 'AMAZON.RepeatIntent': function () { - const newGame = !(this.attributes['speechOutput'] && this.attributes['repromptText']); - this.emitWithState('helpTheUser', newGame); - }, - 'AMAZON.HelpIntent': function () { - const newGame = !(this.attributes['speechOutput'] && this.attributes['repromptText']); - this.emitWithState('helpTheUser', newGame); - }, - 'AMAZON.YesIntent': function () { - if (this.attributes['speechOutput'] && this.attributes['repromptText']) { - this.handler.state = GAME_STATES.TRIVIA; - this.emitWithState('AMAZON.RepeatIntent'); - } else { - this.handler.state = GAME_STATES.START; - this.emitWithState('StartGame', false); - } - }, - 'AMAZON.NoIntent': function () { - const speechOutput = this.t('NO_MESSAGE'); - this.emit(':tell', speechOutput); - }, - 'AMAZON.StopIntent': function () { - const speechOutput = this.t('STOP_MESSAGE'); - this.emit(':ask', speechOutput, speechOutput); - }, - 'AMAZON.CancelIntent': function () { - this.emit(':tell', this.t('CANCEL_MESSAGE')); - }, - 'Unhandled': function () { - const speechOutput = this.t('HELP_UNHANDLED'); - this.emit(':ask', speechOutput, speechOutput); - }, - 'SessionEndedRequest': function () { - console.log(`Session ended in help state: ${this.event.request.reason}`); - }, -}); - -exports.handler = function (event, context) { - const alexa = Alexa.handler(event, context); - alexa.appId = APP_ID; - // To enable string internationalization (i18n) features, set a resources object. - alexa.resources = languageString; - alexa.registerHandlers(newSessionHandlers, startStateHandlers, triviaStateHandlers, helpStateHandlers); - alexa.execute(); -}; diff --git a/examples/apps/alexa-skills-kit-color-expert-python/lambda_function.py b/examples/apps/alexa-skills-kit-color-expert-python/lambda_function.py deleted file mode 100644 index c795c5aff6..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert-python/lambda_function.py +++ /dev/null @@ -1,207 +0,0 @@ -""" -This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit. -The Intent Schema, Custom Slots, and Sample Utterances for this skill, as well -as testing instructions are located at http://amzn.to/1LzFrj6 - -For additional samples, visit the Alexa Skills Kit Getting Started guide at -http://amzn.to/1LGWsLG -""" - -from __future__ import print_function - - -# --------------- Helpers that build all of the responses ---------------------- - -def build_speechlet_response(title, output, reprompt_text, should_end_session): - return { - 'outputSpeech': { - 'type': 'PlainText', - 'text': output - }, - 'card': { - 'type': 'Simple', - 'title': "SessionSpeechlet - " + title, - 'content': "SessionSpeechlet - " + output - }, - 'reprompt': { - 'outputSpeech': { - 'type': 'PlainText', - 'text': reprompt_text - } - }, - 'shouldEndSession': should_end_session - } - - -def build_response(session_attributes, speechlet_response): - return { - 'version': '1.0', - 'sessionAttributes': session_attributes, - 'response': speechlet_response - } - - -# --------------- Functions that control the skill's behavior ------------------ - -def get_welcome_response(): - """ If we wanted to initialize the session to have some attributes we could - add those here - """ - - session_attributes = {} - card_title = "Welcome" - speech_output = "Welcome to the Alexa Skills Kit sample. " \ - "Please tell me your favorite color by saying, " \ - "my favorite color is red" - # If the user either does not reply to the welcome message or says something - # that is not understood, they will be prompted again with this text. - reprompt_text = "Please tell me your favorite color by saying, " \ - "my favorite color is red." - should_end_session = False - return build_response(session_attributes, build_speechlet_response( - card_title, speech_output, reprompt_text, should_end_session)) - - -def handle_session_end_request(): - card_title = "Session Ended" - speech_output = "Thank you for trying the Alexa Skills Kit sample. " \ - "Have a nice day! " - # Setting this to true ends the session and exits the skill. - should_end_session = True - return build_response({}, build_speechlet_response( - card_title, speech_output, None, should_end_session)) - - -def create_favorite_color_attributes(favorite_color): - return {"favoriteColor": favorite_color} - - -def set_color_in_session(intent, session): - """ Sets the color in the session and prepares the speech to reply to the - user. - """ - - card_title = intent['name'] - session_attributes = {} - should_end_session = False - - if 'Color' in intent['slots']: - favorite_color = intent['slots']['Color']['value'] - session_attributes = create_favorite_color_attributes(favorite_color) - speech_output = "I now know your favorite color is " + \ - favorite_color + \ - ". You can ask me your favorite color by saying, " \ - "what's my favorite color?" - reprompt_text = "You can ask me your favorite color by saying, " \ - "what's my favorite color?" - else: - speech_output = "I'm not sure what your favorite color is. " \ - "Please try again." - reprompt_text = "I'm not sure what your favorite color is. " \ - "You can tell me your favorite color by saying, " \ - "my favorite color is red." - return build_response(session_attributes, build_speechlet_response( - card_title, speech_output, reprompt_text, should_end_session)) - - -def get_color_from_session(intent, session): - session_attributes = {} - reprompt_text = None - - if session.get('attributes', {}) and "favoriteColor" in session.get('attributes', {}): - favorite_color = session['attributes']['favoriteColor'] - speech_output = "Your favorite color is " + favorite_color + \ - ". Goodbye." - should_end_session = True - else: - speech_output = "I'm not sure what your favorite color is. " \ - "You can say, my favorite color is red." - should_end_session = False - - # Setting reprompt_text to None signifies that we do not want to reprompt - # the user. If the user does not respond or says something that is not - # understood, the session will end. - return build_response(session_attributes, build_speechlet_response( - intent['name'], speech_output, reprompt_text, should_end_session)) - - -# --------------- Events ------------------ - -def on_session_started(session_started_request, session): - """ Called when the session starts """ - - print("on_session_started requestId=" + session_started_request['requestId'] - + ", sessionId=" + session['sessionId']) - - -def on_launch(launch_request, session): - """ Called when the user launches the skill without specifying what they - want - """ - - print("on_launch requestId=" + launch_request['requestId'] + - ", sessionId=" + session['sessionId']) - # Dispatch to your skill's launch - return get_welcome_response() - - -def on_intent(intent_request, session): - """ Called when the user specifies an intent for this skill """ - - print("on_intent requestId=" + intent_request['requestId'] + - ", sessionId=" + session['sessionId']) - - intent = intent_request['intent'] - intent_name = intent_request['intent']['name'] - - # Dispatch to your skill's intent handlers - if intent_name == "MyColorIsIntent": - return set_color_in_session(intent, session) - elif intent_name == "WhatsMyColorIntent": - return get_color_from_session(intent, session) - elif intent_name == "AMAZON.HelpIntent": - return get_welcome_response() - elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent": - return handle_session_end_request() - else: - raise ValueError("Invalid intent") - - -def on_session_ended(session_ended_request, session): - """ Called when the user ends the session. - - Is not called when the skill returns should_end_session=true - """ - print("on_session_ended requestId=" + session_ended_request['requestId'] + - ", sessionId=" + session['sessionId']) - # add cleanup logic here - - -# --------------- Main handler ------------------ - -def lambda_handler(event, context): - """ Route the incoming request based on type (LaunchRequest, IntentRequest, - etc.) The JSON body of the request is provided in the event parameter. - """ - print("event.session.application.applicationId=" + - event['session']['application']['applicationId']) - - """ - Uncomment this if statement and populate with your skill's application ID to - prevent someone else from configuring a skill that sends requests to this - function. - """ - # if (event['session']['application']['applicationId'] != - # "amzn1.echo-sdk-ams.app.[unique-value-here]"): - # raise ValueError("Invalid Application ID") - - if event['session']['new']: - on_session_started({'requestId': event['request']['requestId']}, - event['session']) - - if event['request']['type'] == "LaunchRequest": - return on_launch(event['request'], event['session']) - elif event['request']['type'] == "IntentRequest": - return on_intent(event['request'], event['session']) - elif event['request']['type'] == "SessionEndedRequest": - return on_session_ended(event['request'], event['session']) diff --git a/examples/apps/alexa-skills-kit-color-expert-python/package.json b/examples/apps/alexa-skills-kit-color-expert-python/package.json deleted file mode 100644 index 6c42250a21..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert-python/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "alexa-skill-kit-sdk-triviaskill", - "version": "1.0.0", - "private": true, - "dependencies": { - "alexa-sdk": "^1.0.10" - } -} diff --git a/examples/apps/alexa-skills-kit-color-expert-python/question.js b/examples/apps/alexa-skills-kit-color-expert-python/question.js deleted file mode 100644 index 152919b7fd..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert-python/question.js +++ /dev/null @@ -1,755 +0,0 @@ -'use strict'; - -module.exports = { - /** - * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods. - * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in. - */ - QUESTIONS_EN_GB: [ - { - 'Reindeer have very thick coats, how many hairs per square inch do they have?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'The 1964 classic Rudolph The Red Nosed Reindeer was filmed in. ': [ - 'Japan', - 'United States', - 'Finland', - 'Germany', - 'Canada', - 'Norway', - 'France', - ], - }, - { - 'Santas reindeer are cared for by one of the Christmas elves, what is his name?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pepper Minstix', - ], - }, - { - 'If all of Santas reindeer had antlers while pulling his Christmas sleigh, they would all be. ': [ - 'Girls', - 'Boys', - 'Girls and boys', - 'No way to tell', - ], - }, - { - 'What do Reindeer eat?': [ - 'Lichen', - 'Grasses', - 'Leaves', - 'Berries', - ], - }, - { - 'What of the following is not true?': [ - 'Caribou live on all continents', - 'Both reindeer and Caribou are the same species', - 'Caribou are bigger than reindeer', - 'Reindeer live in Scandinavia and Russia', - ], - }, - { - 'In what year did Rudolph make his television debut?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Who was the voice of Rudolph in the 1964 classic?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'In 1939 what retailer used the story of Rudolph the Red Nose Reindeer?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Santa\'s reindeer named Donner was originally named what?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Who invented the story of Rudolph?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'In what location will you not find reindeer?': [ - 'North Pole', - 'Lapland', - 'Korvatunturi mountain', - 'Finland', - ], - }, - { - 'What Makes Santa\'s Reindeer Fly?': [ - 'Magical Reindeer Dust', - 'Fusion', - 'Amanita muscaria', - 'Elves', - ], - }, - { - 'Including Rudolph, how many reindeer hooves are there?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Santa only has one female reindeer. Which one is it?': [ - 'Vixen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'In the 1964 classic Rudolph The Red Nosed Reindeer, what was the snowman narrators name?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'What was Rudolph\'s father\'s name?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'In the 1964 movie, What was the name of the coach of the Reindeer Games?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'In the 1964 movie, what is the name of the deer that Rudolph befriends at the reindeer games?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'In the 1964 movie, How did Donner, Rudolph\'s father, try to hide Rudolph\'s nose?': [ - 'Black mud', - 'Bag', - 'Pillow case', - 'Sock', - ], - }, - { - 'In the 1964 movie, what does the Misfit Elf want to be instead of a Santa Elf?': [ - 'Dentist', - 'Reindeer', - 'Toy maker', - 'Candlestick maker', - ], - }, - { - 'In the 1964 movie,what was the Bumble\'s one weakness?': [ - 'Could not swim', - 'Always hungry', - 'Candy canes', - 'Cross eyed', - ], - }, - { - 'In the 1964 movie, what is Yukon Cornelius really in search of?': [ - 'Peppermint', - 'Gold', - 'India', - 'Polar Bears', - ], - }, - { - 'In the 1964 movie, why is the train on the Island of Misfit Toys?': [ - 'Square wheels', - 'No Engine', - 'Paint does not match', - 'It does not toot', - ], - }, - { - 'In the 1964 movie, what is the name of the Jack in the Box?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'In the 1964 movie, why did Santa Claus almost cancel Christmas?': [ - 'Storm', - 'No snow', - 'No toys', - 'The Reindeer were sick', - ], - }, - { - 'In the 1964 movie, what animal noise did the elf make to distract the Bumble?': [ - 'Oink', - 'Growl', - 'Bark', - 'Meow', - ], - }, - { - 'In the 1964 movie, what is the name of the prospector?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'How far do reindeer travel when they migrate?': [ - '3000 miles', - '700 miles', - '500 miles', - '0 miles', - ], - }, - { - 'How fast can a reindeer run?': [ - '48 miles per hour', - '17 miles per hour', - '19 miles per hour', - '14 miles per hour', - '52 miles per hour', - '41 miles per hour', - ], - }, - ], - QUESTIONS_EN_US: [ - { - 'Reindeer have very thick coats, how many hairs per square inch do they have?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'The 1964 classic Rudolph The Red Nosed Reindeer was filmed in. ': [ - 'Japan', - 'United States', - 'Finland', - 'Germany', - 'Canada', - 'Norway', - 'France', - ], - }, - { - 'Santas reindeer are cared for by one of the Christmas elves, what is his name?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pepper Minstix', - ], - }, - { - 'If all of Santas reindeer had antlers while pulling his Christmas sleigh, they would all be': [ - 'Girls', - 'Boys', - 'Girls and boys', - 'No way to tell', - ], - }, - { - 'What do Reindeer eat?': [ - 'Lichen', - 'Grasses', - 'Leaves', - 'Berries', - ], - }, - { - 'What of the following is not true?': [ - 'Caribou live on all continents', - 'Both reindeer and Caribou are the same species', - 'Caribou are bigger than reindeer', - 'Reindeer live in Scandinavia and Russia', - ], - }, - { - 'In what year did Rudolph make his television debut?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Who was the voice of Rudolph in the 1964 classic?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'In 1939 what retailer used the story of Rudolph the Red Nose Reindeer?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Santa\'s reindeer named Donner was originally named what?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Who invented the story of Rudolph?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'In what location will you not find reindeer?': [ - 'North Pole', - 'Lapland', - 'Korvatunturi mountain', - 'Finland', - ], - }, - { - 'What Makes Santa\'s Reindeer Fly?': [ - 'Magical Reindeer Dust', - 'Fusion', - 'Amanita muscaria', - 'Elves', - ], - }, - { - 'Including Rudolph, how many reindeer hooves are there?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Santa only has one female reindeer. Which one is it?': [ - 'Vixen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'In the 1964 classic Rudolph The Red Nosed Reindeer, what was the snowman narrators name?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'What was Rudolph\'s father\'s name?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'In the 1964 movie, What was the name of the coach of the Reindeer Games?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'In the 1964 movie, what is the name of the deer that Rudolph befriends at the reindeer games?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'In the 1964 movie, How did Donner, Rudolph\'s father, try to hide Rudolph\'s nose?': [ - 'Black mud', - 'Bag', - 'Pillow case', - 'Sock', - ], - }, - { - 'In the 1964 movie, what does the Misfit Elf want to be instead of a Santa Elf?': [ - 'Dentist', - 'Reindeer', - 'Toy maker', - 'Candlestick maker', - ], - }, - { - 'In the 1964 movie,what was the Bumble\'s one weakness?': [ - 'Could not swim', - 'Always hungry', - 'Candy canes', - 'Cross eyed', - ], - }, - { - 'In the 1964 movie, what is Yukon Cornelius really in search of?': [ - 'Peppermint', - 'Gold', - 'India', - 'Polar Bears', - ], - }, - { - 'In the 1964 movie, why is the train on the Island of Misfit Toys?': [ - 'Square wheels', - 'No Engine', - 'Paint does not match', - 'It does not toot', - ], - }, - { - 'In the 1964 movie, what is the name of the Jack in the Box?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'In the 1964 movie, why did Santa Claus almost cancel Christmas?': [ - 'Storm', - 'No snow', - 'No toys', - 'The Reindeer were sick', - ], - }, - { - 'In the 1964 movie, what animal noise did the elf make to distract the Bumble?': [ - 'Oink', - 'Growl', - 'Bark', - 'Meow', - ], - }, - { - 'In the 1964 movie, what is the name of the prospector?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'How far do reindeer travel when they migrate?': [ - '3000 miles', - '700 miles', - '500 miles', - '0 miles', - ], - }, - { - 'How fast can a reindeer run?': [ - '48 miles per hour', - '17 miles per hour', - '19 miles per hour', - '14 miles per hour', - '52 miles per hour', - '41 miles per hour', - ], - }, - ], - QUESTIONS_DE_DE: [ - { - 'Rentiere haben ein sehr dickes Fell. Wie viele Haare pro Quadratzentimeter haben sie?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'Der Klassiker aus dem Jahr 1964, Rudolph mit der roten Nase, wurde gedreht in. ': [ - 'Japan', - 'USA', - 'Finnland', - 'Deutschland', - 'Kanada', - 'Norwegen', - 'Frankreich', - ], - }, - { - 'Um die Rentiere des Weihnachtsmanns kümmert sich eine der Weihnachtselfen. Wie heißt sie?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pfeffer Minstix', - ], - }, - { - 'Wenn alle Rentiere des Weihnachtsmanns Geweihe hätten, während sie seinen Weihnachtsschlitten ziehen, wären sie alle. ': [ - 'Weiblich', - 'Männlich', - 'Weiblich und männlich', - 'Kann man nicht sagen', - ], - }, - { - 'Was essen Rentiere?': [ - 'Flechten', - 'Gras', - 'Blätter', - 'Beeren', - ], - }, - { - 'Welche Aussage ist nicht richtig?': [ - 'Karibus leben auf allen Kontinenten', - 'Karibus und Rentiere gehören derselben Gattung an ', - 'Karibus sind größer als Rentiere', - 'Rentiere leben in Skandinavien und Russland', - ], - }, - { - 'In welchem Jahr kam Rudolph ins Fernsehen?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Wer war der Sprecher für Rudolph im klassischen Film aus dem Jahr 1964?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'Welche Handelskette verwendete 1939 die Geschichte von Rudolph mit der roten Nase?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Wie hieß das Rentier des Weihnachtsmanns namens Donner ursprünglich?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Wer hat die Geschichte von Rudolph erfunden?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'Wo findest du keine Rentiere?': [ - 'Nordpol', - 'Lappland', - 'Korvatunturi-Berge', - 'Finnland', - ], - }, - { - 'Warum können die Rentiere des Weihnachtsmanns fliegen?': [ - 'Magischer Staub der Rentiere', - 'Fusion', - 'Amanita muscaria', - 'Elfen', - ], - }, - { - 'Wieviele Rentierhufe gibt es hier einschließlich Rudolph?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Der Weihnachtsmann hat nur ein weibliches Rentier. Wie heißt es?': [ - 'Blitzen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'Wie war der Name des erzählenden Schneemanns im klassischen Film Rudolph mit der roten Nase aus dem Jahr 1964?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'Wie hieß der Vater von Rudolph?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'Wie war der Name des Trainers der Rentierspiele im klassischen Film aus dem Jahr 1964?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'Wie war im klassichen Film aus 1964 der Name des Hirsches, mit dem sich Rudolph befreundete?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'Wie hat der Vater von Rudolph, Donner, im Film aus dem Jahr 1964 versucht, die Nase von Rudolph zu verbergen?': [ - 'Schwarzer Schlamm', - 'Sack', - 'Kissenbezug', - 'Socke', - ], - }, - { - 'Was möchte die Misfit-Elfe im Film aus dem Jahr 1964 werden anstatt eine Elfe für den Weihnachtsmann?': [ - 'Zahnarzt', - 'Rentier', - 'Spielzeugmacher', - 'Kerzenmacher', - ], - }, - { - 'Was war die einzige Schwäche von Bumble im Film aus dem Jahr 1964?': [ - 'Konnte nicht schwimmen', - 'War immer hungrig', - 'Zuckerstangen', - 'Schielte', - ], - }, - { - 'Was sucht Yukon Cornelius in Wirklichkeit im Film aus dem Jahr 1964?': [ - 'Pfefferminz', - 'Gold', - 'Indien', - 'Polarbären', - ], - }, - { - 'Warum befindet sich der Zug im Film aus dem Jahr 1964 auf der Insel des fehlerhaften Spielzeugs?': [ - 'Viereckige Räder', - 'Keine Dampfmaschine', - 'Farbe stimmt nicht', - 'Pfeift nicht', - ], - }, - { - 'Wie lautet der Name des Schachtelmännchens im Film aus dem Jahr 1964?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'Warum hat der Weihnachtsmann im Film aus dem Jahr 1964 Weihnachten beinahe abgesagt?': [ - 'Sturm', - 'Kein Schnee', - 'Kein Spielzeug', - 'Die Rentiere waren krank', - ], - }, - { - 'Welches tierische Geräusch machte die Elfe im Film aus dem Jahr 1964, um den Bumble abzulenken?': [ - 'Oink', - 'Knurr', - 'Wauwau', - 'Miau', - ], - }, - { - 'Wie lautet der Name des Goldsuchers im Film aus dem Jahr 1964?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'Wie weit ziehen Rentiere auf ihren Wanderungen?': [ - '4800 km', - '1100 km', - '800 km', - '0 km', - ], - }, - { - 'Wie schnell läuft ein Rentier?': [ - '77 km pro Stunde', - '27 km pro Stunde', - '30 km pro Stunde', - '22 km pro Stunde', - '83 km pro Stunde', - '65 km pro Stunde', - ], - }, - ], -}; diff --git a/examples/apps/alexa-skills-kit-color-expert-python/template.yaml b/examples/apps/alexa-skills-kit-color-expert-python/template.yaml deleted file mode 100644 index c61acea59b..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert-python/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrates a basic skill built with the Amazon Alexa Skills Kit. -Parameters: - TopicNameParameter: - Type: String -Resources: - alexaskillskitcolorexpertpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: Demonstrates a basic skill built with the Amazon Alexa Skills Kit. - MemorySize: 128 - Timeout: 3 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter - Events: - AlexaSkillEvent: - Type: AlexaSkill diff --git a/examples/apps/alexa-skills-kit-color-expert/index.js b/examples/apps/alexa-skills-kit-color-expert/index.js deleted file mode 100644 index fc1847aefe..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert/index.js +++ /dev/null @@ -1,225 +0,0 @@ -'use strict'; - -/** - * This sample demonstrates a simple skill built with the Amazon Alexa Skills Kit. - * The Intent Schema, Custom Slots, and Sample Utterances for this skill, as well as - * testing instructions are located at http://amzn.to/1LzFrj6 - * - * For additional samples, visit the Alexa Skills Kit Getting Started guide at - * http://amzn.to/1LGWsLG - */ - - -// --------------- Helpers that build all of the responses ----------------------- - -function buildSpeechletResponse(title, output, repromptText, shouldEndSession) { - return { - outputSpeech: { - type: 'PlainText', - text: output, - }, - card: { - type: 'Simple', - title: `SessionSpeechlet - ${title}`, - content: `SessionSpeechlet - ${output}`, - }, - reprompt: { - outputSpeech: { - type: 'PlainText', - text: repromptText, - }, - }, - shouldEndSession, - }; -} - -function buildResponse(sessionAttributes, speechletResponse) { - return { - version: '1.0', - sessionAttributes, - response: speechletResponse, - }; -} - - -// --------------- Functions that control the skill's behavior ----------------------- - -function getWelcomeResponse(callback) { - // If we wanted to initialize the session to have some attributes we could add those here. - const sessionAttributes = {}; - const cardTitle = 'Welcome'; - const speechOutput = 'Welcome to the Alexa Skills Kit sample. ' + - 'Please tell me your favorite color by saying, my favorite color is red'; - // If the user either does not reply to the welcome message or says something that is not - // understood, they will be prompted again with this text. - const repromptText = 'Please tell me your favorite color by saying, ' + - 'my favorite color is red'; - const shouldEndSession = false; - - callback(sessionAttributes, - buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)); -} - -function handleSessionEndRequest(callback) { - const cardTitle = 'Session Ended'; - const speechOutput = 'Thank you for trying the Alexa Skills Kit sample. Have a nice day!'; - // Setting this to true ends the session and exits the skill. - const shouldEndSession = true; - - callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession)); -} - -function createFavoriteColorAttributes(favoriteColor) { - return { - favoriteColor, - }; -} - -/** - * Sets the color in the session and prepares the speech to reply to the user. - */ -function setColorInSession(intent, session, callback) { - const cardTitle = intent.name; - const favoriteColorSlot = intent.slots.Color; - let repromptText = ''; - let sessionAttributes = {}; - const shouldEndSession = false; - let speechOutput = ''; - - if (favoriteColorSlot) { - const favoriteColor = favoriteColorSlot.value; - sessionAttributes = createFavoriteColorAttributes(favoriteColor); - speechOutput = `I now know your favorite color is ${favoriteColor}. You can ask me ` + - "your favorite color by saying, what's my favorite color?"; - repromptText = "You can ask me your favorite color by saying, what's my favorite color?"; - } else { - speechOutput = "I'm not sure what your favorite color is. Please try again."; - repromptText = "I'm not sure what your favorite color is. You can tell me your " + - 'favorite color by saying, my favorite color is red'; - } - - callback(sessionAttributes, - buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)); -} - -function getColorFromSession(intent, session, callback) { - let favoriteColor; - const repromptText = null; - const sessionAttributes = {}; - let shouldEndSession = false; - let speechOutput = ''; - - if (session.attributes) { - favoriteColor = session.attributes.favoriteColor; - } - - if (favoriteColor) { - speechOutput = `Your favorite color is ${favoriteColor}. Goodbye.`; - shouldEndSession = true; - } else { - speechOutput = "I'm not sure what your favorite color is, you can say, my favorite color " + - ' is red'; - } - - // Setting repromptText to null signifies that we do not want to reprompt the user. - // If the user does not respond or says something that is not understood, the session - // will end. - callback(sessionAttributes, - buildSpeechletResponse(intent.name, speechOutput, repromptText, shouldEndSession)); -} - - -// --------------- Events ----------------------- - -/** - * Called when the session starts. - */ -function onSessionStarted(sessionStartedRequest, session) { - console.log(`onSessionStarted requestId=${sessionStartedRequest.requestId}, sessionId=${session.sessionId}`); -} - -/** - * Called when the user launches the skill without specifying what they want. - */ -function onLaunch(launchRequest, session, callback) { - console.log(`onLaunch requestId=${launchRequest.requestId}, sessionId=${session.sessionId}`); - - // Dispatch to your skill's launch. - getWelcomeResponse(callback); -} - -/** - * Called when the user specifies an intent for this skill. - */ -function onIntent(intentRequest, session, callback) { - console.log(`onIntent requestId=${intentRequest.requestId}, sessionId=${session.sessionId}`); - - const intent = intentRequest.intent; - const intentName = intentRequest.intent.name; - - // Dispatch to your skill's intent handlers - if (intentName === 'MyColorIsIntent') { - setColorInSession(intent, session, callback); - } else if (intentName === 'WhatsMyColorIntent') { - getColorFromSession(intent, session, callback); - } else if (intentName === 'AMAZON.HelpIntent') { - getWelcomeResponse(callback); - } else if (intentName === 'AMAZON.StopIntent' || intentName === 'AMAZON.CancelIntent') { - handleSessionEndRequest(callback); - } else { - throw new Error('Invalid intent'); - } -} - -/** - * Called when the user ends the session. - * Is not called when the skill returns shouldEndSession=true. - */ -function onSessionEnded(sessionEndedRequest, session) { - console.log(`onSessionEnded requestId=${sessionEndedRequest.requestId}, sessionId=${session.sessionId}`); - // Add cleanup logic here -} - - -// --------------- Main handler ----------------------- - -// Route the incoming request based on type (LaunchRequest, IntentRequest, -// etc.) The JSON body of the request is provided in the event parameter. -exports.handler = (event, context, callback) => { - try { - console.log(`event.session.application.applicationId=${event.session.application.applicationId}`); - - /** - * Uncomment this if statement and populate with your skill's application ID to - * prevent someone else from configuring a skill that sends requests to this function. - */ - /* - if (event.session.application.applicationId !== 'amzn1.echo-sdk-ams.app.[unique-value-here]') { - callback('Invalid Application ID'); - } - */ - - if (event.session.new) { - onSessionStarted({ requestId: event.request.requestId }, event.session); - } - - if (event.request.type === 'LaunchRequest') { - onLaunch(event.request, - event.session, - (sessionAttributes, speechletResponse) => { - callback(null, buildResponse(sessionAttributes, speechletResponse)); - }); - } else if (event.request.type === 'IntentRequest') { - onIntent(event.request, - event.session, - (sessionAttributes, speechletResponse) => { - callback(null, buildResponse(sessionAttributes, speechletResponse)); - }); - } else if (event.request.type === 'SessionEndedRequest') { - onSessionEnded(event.request, event.session); - callback(); - } - } catch (err) { - callback(err); - } -}; diff --git a/examples/apps/alexa-skills-kit-color-expert/package.json b/examples/apps/alexa-skills-kit-color-expert/package.json deleted file mode 100644 index 6c42250a21..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "alexa-skill-kit-sdk-triviaskill", - "version": "1.0.0", - "private": true, - "dependencies": { - "alexa-sdk": "^1.0.10" - } -} diff --git a/examples/apps/alexa-skills-kit-color-expert/question.js b/examples/apps/alexa-skills-kit-color-expert/question.js deleted file mode 100644 index 152919b7fd..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert/question.js +++ /dev/null @@ -1,755 +0,0 @@ -'use strict'; - -module.exports = { - /** - * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods. - * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in. - */ - QUESTIONS_EN_GB: [ - { - 'Reindeer have very thick coats, how many hairs per square inch do they have?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'The 1964 classic Rudolph The Red Nosed Reindeer was filmed in. ': [ - 'Japan', - 'United States', - 'Finland', - 'Germany', - 'Canada', - 'Norway', - 'France', - ], - }, - { - 'Santas reindeer are cared for by one of the Christmas elves, what is his name?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pepper Minstix', - ], - }, - { - 'If all of Santas reindeer had antlers while pulling his Christmas sleigh, they would all be. ': [ - 'Girls', - 'Boys', - 'Girls and boys', - 'No way to tell', - ], - }, - { - 'What do Reindeer eat?': [ - 'Lichen', - 'Grasses', - 'Leaves', - 'Berries', - ], - }, - { - 'What of the following is not true?': [ - 'Caribou live on all continents', - 'Both reindeer and Caribou are the same species', - 'Caribou are bigger than reindeer', - 'Reindeer live in Scandinavia and Russia', - ], - }, - { - 'In what year did Rudolph make his television debut?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Who was the voice of Rudolph in the 1964 classic?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'In 1939 what retailer used the story of Rudolph the Red Nose Reindeer?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Santa\'s reindeer named Donner was originally named what?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Who invented the story of Rudolph?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'In what location will you not find reindeer?': [ - 'North Pole', - 'Lapland', - 'Korvatunturi mountain', - 'Finland', - ], - }, - { - 'What Makes Santa\'s Reindeer Fly?': [ - 'Magical Reindeer Dust', - 'Fusion', - 'Amanita muscaria', - 'Elves', - ], - }, - { - 'Including Rudolph, how many reindeer hooves are there?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Santa only has one female reindeer. Which one is it?': [ - 'Vixen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'In the 1964 classic Rudolph The Red Nosed Reindeer, what was the snowman narrators name?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'What was Rudolph\'s father\'s name?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'In the 1964 movie, What was the name of the coach of the Reindeer Games?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'In the 1964 movie, what is the name of the deer that Rudolph befriends at the reindeer games?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'In the 1964 movie, How did Donner, Rudolph\'s father, try to hide Rudolph\'s nose?': [ - 'Black mud', - 'Bag', - 'Pillow case', - 'Sock', - ], - }, - { - 'In the 1964 movie, what does the Misfit Elf want to be instead of a Santa Elf?': [ - 'Dentist', - 'Reindeer', - 'Toy maker', - 'Candlestick maker', - ], - }, - { - 'In the 1964 movie,what was the Bumble\'s one weakness?': [ - 'Could not swim', - 'Always hungry', - 'Candy canes', - 'Cross eyed', - ], - }, - { - 'In the 1964 movie, what is Yukon Cornelius really in search of?': [ - 'Peppermint', - 'Gold', - 'India', - 'Polar Bears', - ], - }, - { - 'In the 1964 movie, why is the train on the Island of Misfit Toys?': [ - 'Square wheels', - 'No Engine', - 'Paint does not match', - 'It does not toot', - ], - }, - { - 'In the 1964 movie, what is the name of the Jack in the Box?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'In the 1964 movie, why did Santa Claus almost cancel Christmas?': [ - 'Storm', - 'No snow', - 'No toys', - 'The Reindeer were sick', - ], - }, - { - 'In the 1964 movie, what animal noise did the elf make to distract the Bumble?': [ - 'Oink', - 'Growl', - 'Bark', - 'Meow', - ], - }, - { - 'In the 1964 movie, what is the name of the prospector?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'How far do reindeer travel when they migrate?': [ - '3000 miles', - '700 miles', - '500 miles', - '0 miles', - ], - }, - { - 'How fast can a reindeer run?': [ - '48 miles per hour', - '17 miles per hour', - '19 miles per hour', - '14 miles per hour', - '52 miles per hour', - '41 miles per hour', - ], - }, - ], - QUESTIONS_EN_US: [ - { - 'Reindeer have very thick coats, how many hairs per square inch do they have?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'The 1964 classic Rudolph The Red Nosed Reindeer was filmed in. ': [ - 'Japan', - 'United States', - 'Finland', - 'Germany', - 'Canada', - 'Norway', - 'France', - ], - }, - { - 'Santas reindeer are cared for by one of the Christmas elves, what is his name?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pepper Minstix', - ], - }, - { - 'If all of Santas reindeer had antlers while pulling his Christmas sleigh, they would all be': [ - 'Girls', - 'Boys', - 'Girls and boys', - 'No way to tell', - ], - }, - { - 'What do Reindeer eat?': [ - 'Lichen', - 'Grasses', - 'Leaves', - 'Berries', - ], - }, - { - 'What of the following is not true?': [ - 'Caribou live on all continents', - 'Both reindeer and Caribou are the same species', - 'Caribou are bigger than reindeer', - 'Reindeer live in Scandinavia and Russia', - ], - }, - { - 'In what year did Rudolph make his television debut?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Who was the voice of Rudolph in the 1964 classic?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'In 1939 what retailer used the story of Rudolph the Red Nose Reindeer?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Santa\'s reindeer named Donner was originally named what?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Who invented the story of Rudolph?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'In what location will you not find reindeer?': [ - 'North Pole', - 'Lapland', - 'Korvatunturi mountain', - 'Finland', - ], - }, - { - 'What Makes Santa\'s Reindeer Fly?': [ - 'Magical Reindeer Dust', - 'Fusion', - 'Amanita muscaria', - 'Elves', - ], - }, - { - 'Including Rudolph, how many reindeer hooves are there?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Santa only has one female reindeer. Which one is it?': [ - 'Vixen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'In the 1964 classic Rudolph The Red Nosed Reindeer, what was the snowman narrators name?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'What was Rudolph\'s father\'s name?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'In the 1964 movie, What was the name of the coach of the Reindeer Games?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'In the 1964 movie, what is the name of the deer that Rudolph befriends at the reindeer games?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'In the 1964 movie, How did Donner, Rudolph\'s father, try to hide Rudolph\'s nose?': [ - 'Black mud', - 'Bag', - 'Pillow case', - 'Sock', - ], - }, - { - 'In the 1964 movie, what does the Misfit Elf want to be instead of a Santa Elf?': [ - 'Dentist', - 'Reindeer', - 'Toy maker', - 'Candlestick maker', - ], - }, - { - 'In the 1964 movie,what was the Bumble\'s one weakness?': [ - 'Could not swim', - 'Always hungry', - 'Candy canes', - 'Cross eyed', - ], - }, - { - 'In the 1964 movie, what is Yukon Cornelius really in search of?': [ - 'Peppermint', - 'Gold', - 'India', - 'Polar Bears', - ], - }, - { - 'In the 1964 movie, why is the train on the Island of Misfit Toys?': [ - 'Square wheels', - 'No Engine', - 'Paint does not match', - 'It does not toot', - ], - }, - { - 'In the 1964 movie, what is the name of the Jack in the Box?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'In the 1964 movie, why did Santa Claus almost cancel Christmas?': [ - 'Storm', - 'No snow', - 'No toys', - 'The Reindeer were sick', - ], - }, - { - 'In the 1964 movie, what animal noise did the elf make to distract the Bumble?': [ - 'Oink', - 'Growl', - 'Bark', - 'Meow', - ], - }, - { - 'In the 1964 movie, what is the name of the prospector?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'How far do reindeer travel when they migrate?': [ - '3000 miles', - '700 miles', - '500 miles', - '0 miles', - ], - }, - { - 'How fast can a reindeer run?': [ - '48 miles per hour', - '17 miles per hour', - '19 miles per hour', - '14 miles per hour', - '52 miles per hour', - '41 miles per hour', - ], - }, - ], - QUESTIONS_DE_DE: [ - { - 'Rentiere haben ein sehr dickes Fell. Wie viele Haare pro Quadratzentimeter haben sie?': [ - '13,000', - '1,200', - '5,000', - '700', - '1,000', - '120,000', - ], - }, - { - 'Der Klassiker aus dem Jahr 1964, Rudolph mit der roten Nase, wurde gedreht in. ': [ - 'Japan', - 'USA', - 'Finnland', - 'Deutschland', - 'Kanada', - 'Norwegen', - 'Frankreich', - ], - }, - { - 'Um die Rentiere des Weihnachtsmanns kümmert sich eine der Weihnachtselfen. Wie heißt sie?': [ - 'Wunorse Openslae', - 'Alabaster Snowball', - 'Bushy Evergreen', - 'Pfeffer Minstix', - ], - }, - { - 'Wenn alle Rentiere des Weihnachtsmanns Geweihe hätten, während sie seinen Weihnachtsschlitten ziehen, wären sie alle. ': [ - 'Weiblich', - 'Männlich', - 'Weiblich und männlich', - 'Kann man nicht sagen', - ], - }, - { - 'Was essen Rentiere?': [ - 'Flechten', - 'Gras', - 'Blätter', - 'Beeren', - ], - }, - { - 'Welche Aussage ist nicht richtig?': [ - 'Karibus leben auf allen Kontinenten', - 'Karibus und Rentiere gehören derselben Gattung an ', - 'Karibus sind größer als Rentiere', - 'Rentiere leben in Skandinavien und Russland', - ], - }, - { - 'In welchem Jahr kam Rudolph ins Fernsehen?': [ - '1964', - '1979', - '2000', - '1956', - ], - }, - { - 'Wer war der Sprecher für Rudolph im klassischen Film aus dem Jahr 1964?': [ - 'Billie Mae Richards', - 'Burl Ives', - 'Paul Soles', - 'Lady Gaga', - ], - }, - { - 'Welche Handelskette verwendete 1939 die Geschichte von Rudolph mit der roten Nase?': [ - 'Montgomery Ward', - 'Sears', - 'Macys', - 'Kmart', - ], - }, - { - 'Wie hieß das Rentier des Weihnachtsmanns namens Donner ursprünglich?': [ - 'Dunder', - 'Donny', - 'Dweedle', - 'Dreamy', - ], - }, - { - 'Wer hat die Geschichte von Rudolph erfunden?': [ - 'Robert May', - 'Johnny Marks', - 'Santa', - 'J.K. Rowling', - ], - }, - { - 'Wo findest du keine Rentiere?': [ - 'Nordpol', - 'Lappland', - 'Korvatunturi-Berge', - 'Finnland', - ], - }, - { - 'Warum können die Rentiere des Weihnachtsmanns fliegen?': [ - 'Magischer Staub der Rentiere', - 'Fusion', - 'Amanita muscaria', - 'Elfen', - ], - }, - { - 'Wieviele Rentierhufe gibt es hier einschließlich Rudolph?': [ - '36', - '24', - '16', - '8', - ], - }, - { - 'Der Weihnachtsmann hat nur ein weibliches Rentier. Wie heißt es?': [ - 'Blitzen', - 'Clarice', - 'Cupid', - 'Cupid', - ], - }, - { - 'Wie war der Name des erzählenden Schneemanns im klassischen Film Rudolph mit der roten Nase aus dem Jahr 1964?': [ - 'Sam', - 'Frosty', - 'Burl', - 'Snowy', - ], - }, - { - 'Wie hieß der Vater von Rudolph?': [ - 'Donner', - 'Dasher', - 'Blixen', - 'Comet', - ], - }, - { - 'Wie war der Name des Trainers der Rentierspiele im klassischen Film aus dem Jahr 1964?': [ - 'Comet', - 'Blixen', - 'Donner', - 'Dasher', - ], - }, - { - 'Wie war im klassichen Film aus 1964 der Name des Hirsches, mit dem sich Rudolph befreundete?': [ - 'Fireball', - 'Clarice', - 'Jumper', - 'Vixen', - ], - }, - { - 'Wie hat der Vater von Rudolph, Donner, im Film aus dem Jahr 1964 versucht, die Nase von Rudolph zu verbergen?': [ - 'Schwarzer Schlamm', - 'Sack', - 'Kissenbezug', - 'Socke', - ], - }, - { - 'Was möchte die Misfit-Elfe im Film aus dem Jahr 1964 werden anstatt eine Elfe für den Weihnachtsmann?': [ - 'Zahnarzt', - 'Rentier', - 'Spielzeugmacher', - 'Kerzenmacher', - ], - }, - { - 'Was war die einzige Schwäche von Bumble im Film aus dem Jahr 1964?': [ - 'Konnte nicht schwimmen', - 'War immer hungrig', - 'Zuckerstangen', - 'Schielte', - ], - }, - { - 'Was sucht Yukon Cornelius in Wirklichkeit im Film aus dem Jahr 1964?': [ - 'Pfefferminz', - 'Gold', - 'Indien', - 'Polarbären', - ], - }, - { - 'Warum befindet sich der Zug im Film aus dem Jahr 1964 auf der Insel des fehlerhaften Spielzeugs?': [ - 'Viereckige Räder', - 'Keine Dampfmaschine', - 'Farbe stimmt nicht', - 'Pfeift nicht', - ], - }, - { - 'Wie lautet der Name des Schachtelmännchens im Film aus dem Jahr 1964?': [ - 'Charlie', - 'Sam', - 'Billy', - 'Jack', - ], - }, - { - 'Warum hat der Weihnachtsmann im Film aus dem Jahr 1964 Weihnachten beinahe abgesagt?': [ - 'Sturm', - 'Kein Schnee', - 'Kein Spielzeug', - 'Die Rentiere waren krank', - ], - }, - { - 'Welches tierische Geräusch machte die Elfe im Film aus dem Jahr 1964, um den Bumble abzulenken?': [ - 'Oink', - 'Knurr', - 'Wauwau', - 'Miau', - ], - }, - { - 'Wie lautet der Name des Goldsuchers im Film aus dem Jahr 1964?': [ - 'Yukon Cornelius', - 'Slider Sam', - 'Bumble', - 'Jack', - ], - }, - { - 'Wie weit ziehen Rentiere auf ihren Wanderungen?': [ - '4800 km', - '1100 km', - '800 km', - '0 km', - ], - }, - { - 'Wie schnell läuft ein Rentier?': [ - '77 km pro Stunde', - '27 km pro Stunde', - '30 km pro Stunde', - '22 km pro Stunde', - '83 km pro Stunde', - '65 km pro Stunde', - ], - }, - ], -}; diff --git a/examples/apps/alexa-skills-kit-color-expert/template.yaml b/examples/apps/alexa-skills-kit-color-expert/template.yaml deleted file mode 100644 index 55169f45ff..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrates a basic skill built with the Amazon Alexa Skills Kit. -Parameters: - TopicNameParameter: - Type: String -Resources: - alexaskillskitcolorexpert: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Demonstrates a basic skill built with the Amazon Alexa Skills Kit. - MemorySize: 128 - Timeout: 3 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter - Events: - AlexaSkillEvent: - Type: AlexaSkill diff --git a/examples/apps/alexa-skills-kit-color-expert/testEvent.json b/examples/apps/alexa-skills-kit-color-expert/testEvent.json deleted file mode 100644 index 4c76993ce3..0000000000 --- a/examples/apps/alexa-skills-kit-color-expert/testEvent.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "1.0", - "session": { - "new": false, - "sessionId": "amzn1.echo-api.session.123456789012", - "application": { - "applicationId": "amzn1.ask.skill.987654321" - }, - "attributes": {}, - "user": { - "userId": "amzn1.ask.account.testUser" - } - }, - "context": { - "AudioPlayer": { - "playerActivity": "IDLE" - }, - "System": { - "application": { - "applicationId": "amzn1.ask.skill.987654321" - }, - "user": { - "userId": "amzn1.ask.account.testUser" - }, - "device": { - "supportedInterfaces": { - "AudioPlayer": {} - } - } - } - }, - "request": { - "type": "IntentRequest", - "requestId": "amzn1.echo-api.request.1234", - "timestamp": "2016-10-27T21:06:28Z", - "locale": "en-US", - "intent": { - "name": "MyColorIsIntent", - "slots": { - "Color": { - "name": "Color", - "value": "blue" - } - } - } - } -} diff --git a/examples/apps/alexa-smart-home-skill-adapter/index.js b/examples/apps/alexa-smart-home-skill-adapter/index.js deleted file mode 100644 index 01d4240642..0000000000 --- a/examples/apps/alexa-smart-home-skill-adapter/index.js +++ /dev/null @@ -1,409 +0,0 @@ -'use strict'; - -/** - * This sample demonstrates a smart home skill using the publicly available API on Amazon's Alexa platform. - * For more information about developing smart home skills, see - * https://developer.amazon.com/alexa/smart-home - * - * For details on the smart home API, please visit - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference - */ - -/** - * Mock data for devices to be discovered - * - * For more information on the discovered appliance response please see - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discoverappliancesresponse - */ -const USER_DEVICES = [ - { - // This id needs to be unique across all devices discovered for a given manufacturer - applianceId: 'unique-id-for-non-dimmable-bulb-specific-to-user1', - // Company name that produces and sells the smart home device - manufacturerName: 'SmartHome Product Company', - // Model name of the device - modelName: 'NON-DIMMABLE BULB MODEL ABC', - // Version number of the product - version: '1.0', - // The name given by the user in your application. Examples include 'Bedroom light' etc - friendlyName: 'Smart light', - // Should describe the device type and the company/cloud provider. - // This value will be shown in the Alexa app - friendlyDescription: 'Smart light bulb from SmartHome Product Company', - // Boolean value to represent the status of the device at time of discovery - isReachable: true, - // List the actions the device can support from our API - // The action should be the name of the actions listed here - // https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discoverappliancesresponse - actions: ['turnOn', 'turnOff'], - // not used at this time - additionalApplianceDetails: { - extraDetail1: 'optionalDetailForSkillAdapterToReferenceThisDevice', - extraDetail2: 'There can be multiple entries', - extraDetail3: 'but they should only be used for reference purposes.', - extraDetail4: 'This is not a suitable place to maintain current device state', - }, - }, { - // This id needs to be unique across all devices discovered for a given manufacturer - applianceId: 'unique-id-for-dimmable-bulb-specific-to-user1', - // Company name that produces and sells the smart home device - manufacturerName: 'SmartHome Product Company', - // Model name of the device - modelName: 'DIMMABLE BULB MODEL XYZ', - // Version number of the product - version: '1.0', - // The name given by the user in your application. Examples include 'Bedroom light' etc - friendlyName: 'Dimmable light', - // Should describe the device type and the company/cloud provider. - // This value will be shown in the Alexa app - friendlyDescription: 'Dimmable light bulb from SmartHome Product Company', - // Boolean value to represent the status of the device at time of discovery - isReachable: true, - // List the actions the device can support from our API - // The action should be the name of the actions listed here - // https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discoverappliancesresponse - actions: ['turnOn', 'turnOff', 'setPercentage', 'incrementPercentage', 'decrementPercentage'], - // not used at this time - additionalApplianceDetails: { - }, - }, -]; - -/** - * Utility functions - */ - -function log(title, msg) { - console.log(`[${title}] ${msg}`); -} - -/** - * Generate a unique message ID - * - * TODO: UUID v4 is recommended as a message ID in production. - */ -function generateMessageID() { - return '38A28869-DD5E-48CE-BBE5-A4DB78CECB28'; // Dummy -} - -/** - * Generate a response message - * - * @param {string} name - Directive name - * @param {Object} payload - Any special payload required for the response - * @returns {Object} Response object - */ -function generateResponse(name, payload) { - return { - header: { - messageId: generateMessageID(), - name: name, - namespace: 'Alexa.ConnectedHome.Control', - payloadVersion: '2', - }, - payload: payload, - }; -} - -/** - * Mock functions to access device cloud. - * - * TODO: Pass a user access token and call cloud APIs in production. - */ - -function getDevicesFromPartnerCloud() { - /** - * For the purposes of this sample code, we will return: - * (1) Non-dimmable light bulb - * (2) Dimmable light bulb - */ - return USER_DEVICES; -} - -function isValidToken() { - /** - * Always returns true for sample code. - * You should update this method to your own access token validation. - */ - return true; -} - -function isDeviceOnline(applianceId) { - log('DEBUG', `isDeviceOnline (applianceId: ${applianceId})`); - - /** - * Always returns true for sample code. - * You should update this method to your own validation. - */ - return true; -} - -function turnOn(applianceId) { - log('DEBUG', `turnOn (applianceId: ${applianceId})`); - - // Call device cloud's API to turn on the device - - return generateResponse('TurnOnConfirmation', {}); -} - -function turnOff(applianceId) { - log('DEBUG', `turnOff (applianceId: ${applianceId})`); - - // Call device cloud's API to turn off the device - - return generateResponse('TurnOffConfirmation', {}); -} - -function setPercentage(applianceId, percentage) { - log('DEBUG', `setPercentage (applianceId: ${applianceId}), percentage: ${percentage}`); - - // Call device cloud's API to set percentage - - return generateResponse('SetPercentageConfirmation', {}); -} - -function incrementPercentage(applianceId, delta) { - log('DEBUG', `incrementPercentage (applianceId: ${applianceId}), delta: ${delta}`); - - // Call device cloud's API to set percentage delta - - return generateResponse('IncrementPercentageConfirmation', {}); -} - -function decrementPercentage(applianceId, delta) { - log('DEBUG', `decrementPercentage (applianceId: ${applianceId}), delta: ${delta}`); - - // Call device cloud's API to set percentage delta - - return generateResponse('DecrementPercentageConfirmation', {}); -} - -/** - * Main logic - */ - -/** - * This function is invoked when we receive a "Discovery" message from Alexa Smart Home Skill. - * We are expected to respond back with a list of appliances that we have discovered for a given customer. - * - * @param {Object} request - The full request object from the Alexa smart home service. This represents a DiscoverAppliancesRequest. - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discoverappliancesrequest - * - * @param {function} callback - The callback object on which to succeed or fail the response. - * https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-callback - * If successful, return . - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discoverappliancesresponse - */ -function handleDiscovery(request, callback) { - log('DEBUG', `Discovery Request: ${JSON.stringify(request)}`); - - /** - * Get the OAuth token from the request. - */ - const userAccessToken = request.payload.accessToken.trim(); - - /** - * Generic stub for validating the token against your cloud service. - * Replace isValidToken() function with your own validation. - */ - if (!userAccessToken || !isValidToken(userAccessToken)) { - const errorMessage = `Discovery Request [${request.header.messageId}] failed. Invalid access token: ${userAccessToken}`; - log('ERROR', errorMessage); - callback(new Error(errorMessage)); - } - - /** - * Assume access token is valid at this point. - * Retrieve list of devices from cloud based on token. - * - * For more information on a discovery response see - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discoverappliancesresponse - */ - const response = { - header: { - messageId: generateMessageID(), - name: 'DiscoverAppliancesResponse', - namespace: 'Alexa.ConnectedHome.Discovery', - payloadVersion: '2', - }, - payload: { - discoveredAppliances: getDevicesFromPartnerCloud(userAccessToken), - }, - }; - - /** - * Log the response. These messages will be stored in CloudWatch. - */ - log('DEBUG', `Discovery Response: ${JSON.stringify(response)}`); - - /** - * Return result with successful message. - */ - callback(null, response); -} - -/** - * A function to handle control events. - * This is called when Alexa requests an action such as turning off an appliance. - * - * @param {Object} request - The full request object from the Alexa smart home service. - * @param {function} callback - The callback object on which to succeed or fail the response. - */ -function handleControl(request, callback) { - log('DEBUG', `Control Request: ${JSON.stringify(request)}`); - - /** - * Get the access token. - */ - const userAccessToken = request.payload.accessToken.trim(); - - /** - * Generic stub for validating the token against your cloud service. - * Replace isValidToken() function with your own validation. - * - * If the token is invliad, return InvalidAccessTokenError - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#invalidaccesstokenerror - */ - if (!userAccessToken || !isValidToken(userAccessToken)) { - log('ERROR', `Discovery Request [${request.header.messageId}] failed. Invalid access token: ${userAccessToken}`); - callback(null, generateResponse('InvalidAccessTokenError', {})); - return; - } - - /** - * Grab the applianceId from the request. - */ - const applianceId = request.payload.appliance.applianceId; - - /** - * If the applianceId is missing, return UnexpectedInformationReceivedError - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#unexpectedinformationreceivederror - */ - if (!applianceId) { - log('ERROR', 'No applianceId provided in request'); - const payload = { faultingParameter: `applianceId: ${applianceId}` }; - callback(null, generateResponse('UnexpectedInformationReceivedError', payload)); - return; - } - - /** - * At this point the applianceId and accessToken are present in the request. - * - * Please review the full list of errors in the link below for different states that can be reported. - * If these apply to your device/cloud infrastructure, please add the checks and respond with - * accurate error messages. This will give the user the best experience and help diagnose issues with - * their devices, accounts, and environment - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#error-messages - */ - if (!isDeviceOnline(applianceId, userAccessToken)) { - log('ERROR', `Device offline: ${applianceId}`); - callback(null, generateResponse('TargetOfflineError', {})); - return; - } - - let response; - - switch (request.header.name) { - case 'TurnOnRequest': - response = turnOn(applianceId, userAccessToken); - break; - - case 'TurnOffRequest': - response = turnOff(applianceId, userAccessToken); - break; - - case 'SetPercentageRequest': { - const percentage = request.payload.percentageState.value; - if (!percentage) { - const payload = { faultingParameter: `percentageState: ${percentage}` }; - callback(null, generateResponse('UnexpectedInformationReceivedError', payload)); - return; - } - response = setPercentage(applianceId, userAccessToken, percentage); - break; - } - - case 'IncrementPercentageRequest': { - const delta = request.payload.deltaPercentage.value; - if (!delta) { - const payload = { faultingParameter: `deltaPercentage: ${delta}` }; - callback(null, generateResponse('UnexpectedInformationReceivedError', payload)); - return; - } - response = incrementPercentage(applianceId, userAccessToken, delta); - break; - } - - case 'DecrementPercentageRequest': { - const delta = request.payload.deltaPercentage.value; - if (!delta) { - const payload = { faultingParameter: `deltaPercentage: ${delta}` }; - callback(null, generateResponse('UnexpectedInformationReceivedError', payload)); - return; - } - response = decrementPercentage(applianceId, userAccessToken, delta); - break; - } - - default: { - log('ERROR', `No supported directive name: ${request.header.name}`); - callback(null, generateResponse('UnsupportedOperationError', {})); - return; - } - } - - log('DEBUG', `Control Confirmation: ${JSON.stringify(response)}`); - - callback(null, response); -} - -/** - * Main entry point. - * Incoming events from Alexa service through Smart Home API are all handled by this function. - * - * It is recommended to validate the request and response with Alexa Smart Home Skill API Validation package. - * https://github.com/alexa/alexa-smarthome-validation - */ -exports.handler = (request, context, callback) => { - switch (request.header.namespace) { - /** - * The namespace of 'Alexa.ConnectedHome.Discovery' indicates a request is being made to the Lambda for - * discovering all appliances associated with the customer's appliance cloud account. - * - * For more information on device discovery, please see - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#discovery-messages - */ - case 'Alexa.ConnectedHome.Discovery': - handleDiscovery(request, callback); - break; - - /** - * The namespace of "Alexa.ConnectedHome.Control" indicates a request is being made to control devices such as - * a dimmable or non-dimmable bulb. The full list of Control events sent to your lambda are described below. - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#payload - */ - case 'Alexa.ConnectedHome.Control': - handleControl(request, callback); - break; - - /** - * The namespace of "Alexa.ConnectedHome.Query" indicates a request is being made to query devices about - * information like temperature or lock state. The full list of Query events sent to your lambda are described below. - * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/smart-home-skill-api-reference#payload - * - * TODO: In this sample, query handling is not implemented. Implement it to retrieve temperature or lock state. - */ - // case 'Alexa.ConnectedHome.Query': - // handleQuery(request, callback); - // break; - - /** - * Received an unexpected message - */ - default: { - const errorMessage = `No supported namespace: ${request.header.namespace}`; - log('ERROR', errorMessage); - callback(new Error(errorMessage)); - } - } -}; diff --git a/examples/apps/alexa-smart-home-skill-adapter/package.json b/examples/apps/alexa-smart-home-skill-adapter/package.json deleted file mode 100644 index a8fb34e653..0000000000 --- a/examples/apps/alexa-smart-home-skill-adapter/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "alexa-skill-kit-sdk-howtoskill", - "version": "1.0.0", - "private": true, - "dependencies": { - "alexa-sdk": "^1.0.10" - } -} diff --git a/examples/apps/alexa-smart-home-skill-adapter/recipes.js b/examples/apps/alexa-smart-home-skill-adapter/recipes.js deleted file mode 100644 index 9611d3fa89..0000000000 --- a/examples/apps/alexa-smart-home-skill-adapter/recipes.js +++ /dev/null @@ -1,1536 +0,0 @@ -/* eslint-disable func-names */ -/* eslint-disable max-len */ -/* eslint quote-props: ['error', 'consistent']*/ -module.exports = { - 'RECIPE_EN_GB': { - 'snow golem': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'pillar quartz block': 'A pillar of quartz can be obtained by placing a block of quartz on top of a block of quartz in mine craft.', - 'firework rocket': 'A firework rocket can be crafted by placing a firework star in the left middle square, a piece of paper in the center square, and gunpowder in the right middle square in a crafting table. Similar to a firework star, a firework rocket can have more gunpowder added in the bottom row to increase the duration of a rocket.', - 'rabbit stew': 'Rabbit stew can be crafted by placing cooked rabbit in the top middle square, a carrot in the middle left square, a baked potato in the center square, any type of mushroom in the middle right square, and a bowl in the bottom middle square.', - 'cauldron': 'A cauldron can be created by placing iron ingots in all squares but the top middle and very center squares in a crafting table.', - 'stone shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'red carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'book and quill': 'A book and quill can be crafted by placing a book in the middle left square, an ink sac in the very center square, and a feather in the bottom middle square in a crafting table.', - 'item frame': 'An item frame can be crafted by placing leather in the very center square, and eight sticks surrounding it.', - 'map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'sticky piston': 'A sticky piston can be crafted by placing a slime ball on top of a piston in a crafting window', - 'bread': 'Bread can be crafted by placing three wheat across a row in a crafting table.', - 'wooden pick ax': 'All types of pick axs can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'shears': 'Shears can be crafted by placing two Iron Ingots diagonal from each other.', - 'raw beef': 'Raw Beef will drop from the death of a Cow or Moo shrooms.', - 'smooth red sandstone': 'Smooth red sandstone can be crafted by placing four red sandstone in a two by two grid in a crafting window.', - 'prismarine crystals': 'Prismarine Crystals can be obtained by defeating Guardians and Elder Guardians.', - 'oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'wooden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'jungle fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'activator rail': 'An activator rail can be crafted by placing a red stone torch in the very center square, sticks above and beneath it, and then six iron ingots in the remaining squares in a crafting table.', - 'farmland': 'Farmland can be created by plowing the land with a hoe.', - 'gold ore': 'Gold ore can be obtained by breaking gold ore blocks with an iron pick ax or better', - 'andesite': 'Andesite can be mined with a pick ax or crafted by placing diorite next to cobblestone in a crafting table.', - 'rose red': 'Rose red can be crafted by placing a poppy into a crafting table.', - 'iron axe': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'light blue dye': 'Light blue dye can be crafted by placing lapis lazuli next to bone meal in a crafting window.', - 'gray dye': 'Gray dye can be crafted by placing bonemeal next to an ink sac in a crafting window', - 'blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'golden leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'dark oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'wither mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'spider eye': 'A spider eye is randomly dropped by killing spiders or witches.', - 'magenta stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'brown stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'pumpkin pie': 'A pumpkin pie can be crafted by placing a pumpkin in the left middle square, sugar in the very center square, and an egg in the bottom middle square in a crafting table.', - 'snowball': 'A snowball can be obtained by breaking snow with a shovel.', - 'juke box': 'A juke box is crafted by placing a diamond in the very center square and wood planks all around that in a crafting table', - 'sand': 'Sand can be obtained by breaking sand blocks.', - 'dead bush': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'brick slab': 'A brick slab can be crafted by placing three brick blocks in a row in a crafting table.', - 'lily pad': 'Lily pads can be found naturally on water in swamplands or underground lakes.', - 'leather pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'mossy cobblestone wall': 'A mossy cobblestone wall is crafted by placing six mossy cobblestone across the bottom two rows in a crafting table.', - 'eleven disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'purple stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'magenta stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'mall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'jungle wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diamond ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'empty map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'stone pressure plate': 'A stone pressure plate can be crafted by placing two smooth stone, next to each other, horizontally, in a crafting window.', - 'trapdoor': 'Trapdoors can be crafted with either wooden planks or iron ingots. To craft a wooden trapdoor, place wooden planks in all spaces in the bottom two rows. To craft an iron trapdoor, place iron ingots in a two by two grid in a crafting table.', - 'gold boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'red stone wire': 'Redstone wire is simply red stone placed on the floor.', - 'piston': 'A piston can be crafted by placing an iron ingot in the center square, red stone in the bottom middle square, wooden planks across the top row, and cobblestone in the remaining squares.', - 'white stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'sugar': 'Sugar can be obtained by placing sugar cane in a crafting window.', - 'chain mail chest plate': 'Chain mail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'feather': 'Feathers can be randomly obtained by killing chickens.', - 'light blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'stone pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'pink carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'monster spawner': 'Monster spawners can not be obtained without cheats in mine craft.', - 'golden carrot': 'A golden carrot can be crafted by placing a carrot in the very middle square and eight gold nuggets surrounding that.', - 'stick': 'A stick can be crafted by placing a wooden plank on top of a wooden plank in a crafting window.', - 'diamond block': 'A diamond block can be crafted by placing diamonds in every square in a crafting table.', - 'green stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cooked chicken': 'Raw Chicken can be cooked by smelting it in a furnace. Alternately, Cooked Chicken has a chance of dropping when a Chicken dies while on fire.', - 'thirteen disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'wooden trapdoor': 'A wooden trapdoor can be crafted by placing wooden planks in all spaces in the bottom two rows in a crafting table.', - 'oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'crafting bench': 'A crafting bench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'nether quartz ore': 'Nether quartz ore can be randomly found in the nether. To obtain the ore instead of nether quartz, you will need to use a silk touch pick ax.', - 'golden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stone hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'coal ore': 'Coal ore can be obtained by breaking a coal ore block with a pick ax that is enchanted with silk touch', - 'dark oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 't.n.t.': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'brick': 'A brick can be crafted by smelting clay in a furnace.', - 'potato': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'orange carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'ink sack': 'An ink sack can be obtained by killing a squid.', - 'red stone': 'Redstone can be obtained by breaking red stone ore with an iron pick ax or better.', - 'dark oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diorite': 'Diorite can be mined with a pick ax or crafted by combining cobblestone and nether quartz in a two by two grid in a crafting table.', - 'workbench': 'A workbench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'jungle fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'magenta wool': 'Magenta wool can be crafted by placing magenta dye next to any color wool in a crafting window.', - 'dirt': 'Dirt can be obtained by breaking grass or dirt with a shovel.', - 'armor stand': 'An Armor Stand can be crafted with six sticks and one stone slab. Take three sticks and place it across the first row. Take the remaining three sticks and place one each in the bottom left, bottom right, and center middle. Place the stone slab in the bottom middle.', - 'cooked fish': 'Cooked fish is obtained by cooking fish in a furnace.', - 'lever': 'A lever can be crafted by placing a stick on top of cobblestone in a crafting window.', - 'leash': 'A leash can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'cooked rabbit': 'Cooked rabbit can be obtained by cooking raw rabbit in a furnace. Alternately, Cooked Rabbit has a chance of dropping when a Rabbit dies while on fire.', - 'jungle wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with hopper': 'A Mine cart With a Hopper can be crafted by placing a Hopper on top of a Mine cart in a crafting table.', - 'fermented spider eye': 'Fermented spider eye can be obtained by placing a brown mushroom in the middle left square, sugar in the very center square, and a spider eye in the bottom middle square in a crafting table.', - 'raw fish': 'Raw fish is randomly obtained by fishing.', - 'brown stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'sign': 'A sign is crafted by placing wooden planks in the top two rows and a stick in the bottom middle square.', - 't.n.t': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'hopper': 'A hopper can be crafted by placing a chest in the very center square, and then iron ingots in every square but the top middle, bottom left, and bottom right squares in a crafting grid.', - 'blaze rod': 'Blaze rods can be randomly obtained by killing blazes.', - 'red stone comparator': 'A red stone comparator can be crafted by placing three smooth stone across the bottom row, a nether quartz in the center square, and three red stone torches surrounding the nether quartz in a crafting table.', - 'bone': 'Bones can be obtained by killing skeletons.', - 'golden horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'golden pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'rail': 'A rail can be crafted by placing a stick in the very middle square and iron ingots vertically in both the first and last column in a crafting table.', - 'wheat seeds': 'Wheat seeds are obtained by harvesting wheat.', - 'birch fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'purple stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'golden chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'leather boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'diamond shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'leather leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sand': 'Red sand can be found in Mesa biomes.', - 'vines': 'Vines can only be harvested with shears. Vines spawn naturally in jungle trees or in swamplands.', - 'glass bottle': 'A glass bottle is crafted by creating a V shape with three glass blocks in a crafting table.', - 'red stone ore': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'emerald block': 'Emerald blocks can be crafted by placing nine emeralds in a three by three grid in a crafting table.', - 'granite': 'Granite can be mined with a pick ax or crafted by placing Diorite and a nether quartz next to each other in a crafting table.', - 'brown wool': 'Brown wool can be crafted by placing brown dye next to any color wool in a crafting window.', - 'golden apple': 'A golden apple can be crafted by placing an apple in the very center square and eight gold ingots surrounding it.', - 'birch leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'white wool': 'White wool can be crated by placing four string in a two by two grid in a crafting window. It can also be obtained by placing bone meal next to any color wool in a crafting window', - 'purple carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'hardened clay': 'Hardened clay can be crafted by smelting a clay block in a furnace.', - 'zombie mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'iron trapdoor': 'An iron trapdoor can be crafted by placing iron ingots in a two by two grid in a crafting window.', - 'flower pot': 'A flower pot is crafted by placing three bricks in a V shape in a crafting table.', - 'iron ore': 'Iron ore can be obtained by breaking iron ore blocks with a stone pick ax or better', - 'jungle wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'jungle door': 'A Jungle Door can be crafted by placing six Jungle Planks down the first two columns.', - 'golden ax': 'All types of axes can be crafted by placing three of the desired materials in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'packed ice': 'Packed ice can be found in the rare ice plains spikes biome and can only be obtained with a silk touch tool.', - 'bricks': 'Bricks can be crafted by smelting clay in a furnace.', - 'light blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'dead shrub': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'dropper': 'A dropper can be crafted by placing red stone in the middle bottom square, and cobblestone in every other square but the center one.', - 'chest': 'A chest is crafted by placing wooden planks, in every square but the middle square, in a crafting table.', - 'raw chicken': 'Raw Chicken will drop from the death of a Chicken.', - 'raw salmon': 'Raw salmon is randomly obtained by fishing.', - 'tripwire hook': 'A tripwire hook can be crafted by placing an iron ingot on top of a stick on top of a wood plank in a crafting table.', - 'oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with command block': 'A mine cart with a command block can not be obtained without cheats.', - 'eye of ender': 'An eye of ender can be crafted by placing blaze power next to an ender pearl in a crafting window.', - 'block of coal': 'A block of coal can be crafted by placing coal in a three by three grid in a crafting window.', - 'nether star': 'A Nether Star can be obtained by defeating the Wither.', - 'gravel': 'Gravel can be obtained by breaking gravel blocks', - 'blue wool': 'Blue wool can be crafted by placing lapis lazuli next to any color wool in a crafting window.', - 'nether quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'rotten flesh': 'Rotten flesh can be randomly obtained by killing zombies.', - 'magenta carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'white stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'birch fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'carrots': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'purple dye': 'Purple dye can be crafted by placing lapis lazuli next to rose red in a crafting window.', - 'lapis lazuli block': 'A lapis lazuli block can be obtained by entirely filling a crafting table with lapis lazuli.', - 'obsidian': 'Obsidian can be mined with a diamond pick or created by placing water on top of lava. ', - 'mellohi disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music discs are found in eight percent of dungeon chests.', - 'gray wool': 'Gray wool can be crafted by placing gray dye next to any color wool in a crafting window.', - 'trapped chest': 'A trapped chest can be crafted by placing a tripwire hook next to a chest in a crafting window.', - 'light gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'red mushroom': 'Red mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'puffer fish': 'A puffer fish can be randomly obtained by fishing.', - 'emerald': 'Emeralds can be obtained by harvesting emerald ore.', - 'wooden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'golden helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'melon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest mine carts in abandoned mine shafts.', - 'clay block': 'Clay is commonly found at the bottoms of rivers and lakes in shallow, circular patches. Clay blocks can also be found commonly in swamps.', - 'anvil': 'An anvil can be crafted by placing three blocks of iron across the top row, an iron ingot in the very center square, and then three iron ingots across the bottom row in a crafting table.', - 'daylight sensor': 'A daylight sensor can be crafted by placing three glass across the top row, three nether quartz across the middle grow, anad three wooden slabs across the bottom row in a crafting table.', - 'lead': 'A lead can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'sandstone': 'Sandstone can be obtained in deserts or crafted by combining sand together in a two by two square.', - 'leather tunic': 'All chest pieces are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'black stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'lime stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mine cart with t.n.t': 'A Mine cart with T.N.T can be crafted by placing a T.N.T on top of a Mine cart in a crafting table.', - 'clock': 'A clock is crafted by placing red stone in the very center square and surrounding it with four gold ingots in a crafting table.', - 'black carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'cocoa': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'gold ingot': 'Gold ingots can be obtained by smelting gold ore in a furnace.', - 'stone brick slab': 'A stone brick slab can be crafted by placing three stone bricks in a row in a crafting table.', - 'clown fish': 'A clown fish can be randomly obtained by fishing.', - 'pumpkin seeds': 'Pumpkin seeds can be crafted by placing a pumpkin in a crafting window.', - 'mossy stone brick': 'Mossy stone brick can be crafted by placing vines next to stone bricks in a crafting window. Mossy stone brick can also be found naturally in strongholds.', - 'cobweb': 'Cobwebs can be obtained by using shears or a sword that is enchanted with silk touch', - 'milk bucket': 'A milk bucket can be obtained by right clicking on a cow with an iron bucket.', - 'iron helmet': 'All helmets are crafted by placing the desired material, in all squares but the very center square, and the bottom row, in a crafting table.', - 'yellow stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond': 'Diamond can be obtained by breaking diamond ore with an iron pick ax or better.', - 'stone sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'cobblestone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'bed': 'A bed can be crafted by placing three wool across the top row and three wooden planks across the middle row in a crafting table.', - 'birch wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'quartz slab': 'A quartz slab can be crafted by placing three quartz blocks in a row in a crafting table.', - 'sponge': 'Sponges can be obtained by killing an elder guardian or randomly finding them in ocean monuments', - 'skeleton mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'bucket': 'A bucket can be crafted by placing three iron ingots in a V shape in a crafting table.', - 'diamond sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'golden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'spruce wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'iron bars': 'Iron bars can be crafted by placing six iron ingots across the bottom two rows in a crafting table. Iron bars can also be found naturally in strongholds.', - 'raw rabbit': 'Raw rabbit can be randomly obtained by killing a rabbit.', - 'yellow carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'carrot on a stick': 'A carrot on a stick can be crafted by placing a fishing pole in the middle left square and a carrot in the bottom middle square in a crafting window.', - 'raw pork chop': 'A raw pork chop can be obtained by killing a pig.', - 'furnace': 'A furnace can be crafted by placing cobblestone in every square but the middle square in a crafting table.', - 'nether brick fence': 'A nether brick fence can be crafted by placing six nether brick across the bottom two rows in a crafting table.', - 'fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'diamond horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red sandstone slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood plank': 'Birch wood planks can be obtained by placing birch wood in a crafting table.', - 'bedrock': 'Bedrock can not be obtained by a player without cheats. It is the bottom most block in the game.', - 'saddle': 'Saddles can not be crafted and can only be obtained by finding them in chests inside dungeons, abandoned mine shafts, nether fortresses, desert temples, or jungle temples.', - 'light gray dye': 'Light gray dye can be crafted by placing two bone meal in a vertical row next to an ink sac in a crafting window.', - 'jungle leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'blocks disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'pumpkin': 'Pumpkins can be rarely be found on grass in most biomes.', - 'baked potato': 'A baked potato can be obtained by smelting a potato in a furnace.', - 'leather': 'Leather can be randomly obtained by killing cows or horses.', - 'light gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'end stone': 'End stone can be found naturally in the end dimension.', - 'chainmail leggings': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'rabbit\'s foot': 'A rabbit\'s foot can be obtained rarely by killing a rabbit.', - 'glass': 'Glass can be obtained by smelting sand in a furnace.', - 'stone': 'Stone can be made by smelting cobblestone in a furnace.', - 'prismarine': 'Prismarine can be crafted by placing prismarine shards in a two by two grid in a crafting window.', - 'compass': 'A compass is crafted by placing red stone in the very center square, and surrounding it with four iron ingots, in a crafting table.', - 'green stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'gold leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'command block': 'Command blocks can not be obtained without cheats in minecraft.', - 'dispenser': 'A dispenser can be created by placing a bow in the very center square, red stone right beneath that, and cobblestone in every other square.', - 'poisonous potato': 'A poisonous potato will randomly be dropped when harvesting potatoes.', - 'apple': 'Apples randomly drop from oak and dark oak leaves. They can also be randomly found in chests in strongholds or villages.', - 'red flower': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'magenta dye': 'Magenta dye can be crafted by placing purple dye next to pink dye in a crafting window.', - 'brown carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'prismarine shard': 'Prismarine Shards can be obtained by defeating Guardians and Elder Guardians.', - 'red stone block': 'A red stone block can be crafted by placing nine red stone in a three by three grid in a crafting table.', - 'yellow stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'dandelion yellow': 'Dandelion yellow is the equivalent of yellow dye in minecraft. It can be crafted by placing a dandelion or a sunflower in a crafting window.', - 'acacia wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'sandstone slab': 'A sandstone slab can be crated by placing three sandstone blocks in a row in a crafting table.', - 'gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished granite': 'Polished Granite can be crafted by placing four granite in a two by two grid in a crafting table.', - 'mine cart': 'A mine cart is crafted by placing five iron ingots in a U shape in a crafting table.', - 'brown stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'cyan stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'book': 'A book is crafted by creating a two by two grid where the bottom right square is leather and all other squares are paper in a crafting window.', - 'mine cart with a chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'acacia sapling': 'Acacia saplings can be randomly obtained by breaking acacia leaves.', - 'paper': 'Paper is crafted by placing three sugar cane, across a row, in a crafting table.', - 'gold chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cyan stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mushroom stew': 'Mushroom stew is crafted by placing a red mushroom in the middle left square, a brown mushroom in the very center square, and a bowl in the bottom middle square in a crafting table.', - 'nether brick': 'Nether Brick can be mined with a pick ax, or crafted by placing four Nether Bricks in a two by two square in a crafting table.', - 'magma cream': 'Magma cream can be crafted by placing blaze powder next to a slime ball in a crafting window.', - 'snow': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'orange dye': 'Orange dye can be crafted by placing rose red next to dandelion yellow in a crafting window.', - 'potion': 'A potion is created by utilizing a brewing stand, cauldron, and water bottles.', - 'lime stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'white stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'boat': 'A boat can be obtained by making a U shape with five wooden planks.', - 'dark prismarine': 'Dark prismarine can be crafted by placing an ink sac in the very center square, and then eight placing prismarine shards around it.', - 'oak door': 'A Oak Door can be crafted by placing six Oak Planks down the first two columns.', - 'cocoa beans': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'red wool': 'Red wool can be crafted by placing rose red next to any color wool in a crafting window.', - 'cooked mutton': 'Cooked mutton can be obtained by cooking raw mutton in a furnace. Alternately, one to two pieces of Cooked Mutton are dropped when a sheep dies while on fire.', - 'dark oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'iron door': 'An Iron Door can be crafted by placing six Iron Ingots down the first two columns.', - 'painting': 'A painting is crafted by placing wool in the very center square and surrounding it with eight sticks.', - 'spruce leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'pink stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'acacia wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'dark oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'chiseled sandstone': 'Chiseled sandstone can be created by placing a sandstone slab on top of a sandstone slab, in a crafting window.', - 'oak wood plank': 'Oak wood planks can be obtained by placing oak wood in a crafting table.', - 'cooked salmon': 'Cooked salmon is obtained by cooking salmon in a furnace.', - 'iron shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'enchanting table': 'An enchanting table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'red stone repeater': 'A red stone repeater can be crafted by placing smooth stone in all three squares across the bottom row, red stone in the very middle square, and red stone torches on both sides of the red stone.', - 'far disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'green carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron ingot': 'Iron ingots can be obtained by smelting iron ore in a furnace.', - 'orange wool': 'Orange wool can be crafted by placing orange dye next to any color wool in a crafting window.', - 'jungle sapling': 'Jungle saplings can be randomly obtained by breaking jungle leaves.', - 'stone slab': 'A stone slab can be crafted by placing three stone blocks in a row in a crafting table.', - 'light blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'cyan dye': 'Cyan dye can be crafted by placing lapis lazuli next to cactus green in a crafting window.', - 'steak': 'Raw Beef can be cooked into Steak by smelting it in a furnace. Alternately, Steak has a chance of dropping when a Cow or Moo shroom dies while on fire.', - 'orange stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'spruce fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'coal': 'Coal can be obtained by breaking a coal ore block with a wooden pick ax or better.', - 'potatoes': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'light gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'egg': 'Eggs are randomly produced by chickens. Throwing an egg has a chance to create a new chicken.', - 'spruce wood plank': 'Spruce wood planks can be obtained by placing spruce wood in a crafting table.', - 'orange stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'acacia wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'light gray wool': 'Light gray wool can be crafted by placing light gray dye next to any color wool in a crafting window.', - 'hay bale': 'A hay bale can be crafted by placing wheat in a three by three grid in a crafting table.', - 'clay': 'Clay is obtained by breaking clay blocks with a non silk touch tool.', - 'bowl': 'A bowl can be crafted by placing three wooden planks in a v shape in a crafting table.', - 'leather helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'pink stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'diamond chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'yellow stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'snowman': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'diamond ore': 'Diamond ore can be found in the bottom sixteen layers on the map. One can break diamond ore with an iron pick ax or better. This will cause the diamond ore to break into a diamond. To obtain the ore, you will need to use a pick ax with the silk touch enchant.', - 'banner': 'A Banner can be crafted by placing six wool across the top two rows, then placing a stick on the bottom middle. The banner will take on the color of the wool you choose.', - 'stone ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'firework star': 'A firework star can be crafted by placing gunpower in the middle left square and any color dye in the center square in a crafting table. A firework star can also be crafted with optional ingredients such as diamonds, glow stone dust, or feathers, that are placed directly beneath the dye in a crafting table.', - 'nether wart': 'Nether warts can be naturally found in nether fortresses as a plant.', - 'red stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'quartz block': 'A quartz block can be crafted by placing four nether quartz in a two by two grid in a crafting table.', - 'poppy': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'acacia fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'cactus': 'Cactus can be found naturally in desert biomes. ', - 'spruce door': 'A Spruce Door can be crafted by placing six Spruce Planks down the first two columns.', - 'cat disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'flint and steel': 'Flint and steel can be crafted by placing an iron ingot to the left of flint in a crafting window.', - 'gold pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'slime ball': 'Slime balls are randomly dropped by killing slimes.', - 'cooked porkchop': 'A cooked porkchop can be obtained by cooking a raw porkchop in a furnace or by lighting a pig on fire.', - 'polished andesite': 'Polished Andesite can be crafted by placing four andesite in a two by two grid in a crafting table.', - 'prismarine bricks': 'Prismarine bricks can be crafted by placing prismarine shards in a three by three grid in a crafting table.', - 'wither': 'A wither can be created by placing three wither skulls on top of soul sand that is placed on the ground in a T shape.', - 'lime dye': 'Lime dye can be crafted by placing cactus green next to bone meal in a crafting window.', - 'blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'door': 'A door can be crafted by placing six Planks, down the first two columns, in a crafting table.', - 'tripwire': 'Tripwire is simply string next to a tripwire hook.', - 'enchantment table': 'An enchantment table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'cyan carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished diorite': 'Polished Diorite can be crafted by placing four diorite in a two by two grid in a crafting table.', - 'golden boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'iron block': 'An iron block can be crafted by placing iron ingots in a three by three grid in a crafting table.', - 'acacia leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'dark oak sapling': 'Dark oak saplings can be randomly obtained by breaking dark oak leaves', - 'diamond hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'dandelion': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'lapis lazuli': 'Can be obtained by breaking lapis lazuli ore with a stone pick ax or better', - 'sugar cane': 'Sugar cane can be found naturally near water,', - 'birch door': 'A Birch Door can be crafted by placing six Birch Planks down the first two columns.', - 'cactus green': 'Cactus green can be crafted by smelting a cactus in a furnace.', - 'gold block': 'A gold block can be crafted by placing gold ingots in a three by three grid in a crafting table.', - 'smooth sandstone': 'Smooth sandstone can be created by placing sandstone in a two by two grid in a crafting window', - 'magenta stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'note block': 'A note block is crafted by placing red stone in the very center square and wooden planks all around that in a crafting table', - 'snow block': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'diamond leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sandstone': 'Red sandstone can be crafted by placing four red sand in a two by two grid in a crafting window.', - 'orange stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'slime block': 'A slime block can be crafted by placing slime balls in a three by three grid in a crafting window.', - 'bookshelf': 'A bookshelf is crafted by placing books across the middle row and wooden planks across the top and bottom rows', - 'cake': 'Cake can be crafted by placing three buckets of milk across the top row, sugar in the left middle, and right middle squares, an egg in the very center square, and three wheat across the bottom squares in a crafting table.', - 'wooden button': 'A wooden button can be crafted by placing a single wooden plank in a crafting window.', - 'chiseled quartz block': 'A chiseled quartz block can be obtained by placing a quartz slab on top of a quartz slab in a crafting table.', - 'stone button': 'A stone button can be crafted by placing a single piece of smooth stone in a crafting window.', - 'glow stone dust': 'Glow stone dust is obtained by breaking glow stone blocks.', - 'lime stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cobblestone wall': 'A cobblestone wall is crafted by placing six cobblestone across the bottom two rows in a crafting table.', - 'name tag': 'Name Tags can only be obtained in three ways. The first way is by finding it in a Dungeon chest. The second way is by fishing. The last way Name Tags can be obtained is by trading with the Librarian Villagers for twenty to twenty two Emeralds.', - 'gunpowder': 'Gunpowder can be randomly obtained by killing creepers.', - 'blaze powder': 'Blaze powder can be obtained by placing a blaze row in a crafting window.', - 'brewing stand': 'A brewing stand can be crafted by placing a blaze rod in the center square, and three cobblestone across the bottom row in a crafting table.', - 'torch': 'A torch can be crafted by placing a piece of coal on top of a stick.', - 'yellow wool': 'Yellow wool can be crafted by placing dandelion yellow next to any color wool in a crafting window.', - 'watermelon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest minecarts in abandoned mine shafts.', - 'wait disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'glistering melon': 'A glistering melon can be crafted by placing a melon in the very center square and surrounding it with eight gold nuggets in a crafting table.', - 'netherrack': 'Netherrack can be found commonly throughout the Nether dimension.', - 'leather chest plate': 'All chest places are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'wooden slab': 'A wooden slab can be crafted by placing three wooden planks in a row in a crafting table.', - 'nether brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ice': 'Ice can be found naturally in snow biomes. If broken, or placed near a heat source, ice will turn into water. To obtain an ice block, one would need to mine it with a silk touch pick ax.', - 'large fern': 'Large ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'nether brick slab': 'A nether brick slab can be crafted by placing three nether brick in a row in a crafting table.', - 'spruce wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'iron hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'fern': 'Ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'sea lantern': 'A sea lantern can be crafted by placing prismarine shards in the four corners of a crafting table, and then placing prismarine crystals in every other square.', - 'cookie': 'A cookie can be crafted by placing wheat, horizontally, on both sides of cocoa beans in a crafting table.', - 'melon seeds': 'Melon seeds can be crafted by placing a slice of melon in a crafting window.', - 'gold nugget': 'A gold nugget can be crafted by placing a single gold ingot into a crafting window. They can also be randomly obtained by killing a zombie pig men.', - 'red stone ore block': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'diamond helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'spruce fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'golden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'acacia wood plank': 'Acacia wood planks can be obtained by placing acacia wood in a crafting table', - 'diamond pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'lapis lazuli ore': 'Lapis Lazuli Ore can be only be obtained by using a pick ax with the silk touch enchant.', - 'raw mutton': 'Raw mutton can be obtained by killing a sheep.', - 'quartz stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'brick block': 'A brick block can be crafted by placing clay bricks in a two by two grid in a crafting window.', - 'cobblestone slab': 'A cobblestone slab can be crafted by placing three cobblestone blocks in a row in a crafting table.', - 'emerald ore': 'Emerald ore can only be found in extreme hills biomes between layers four and thirty-two. It can be mined with an iron pick ax or better to obtain an emerald. To obtain the ore itself, you will need a silk touch pick ax.', - 'yellow flower': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'jack o\'lantern': 'A jack o\'lantern can be crafted by placing a pumpkin on top of a torch in a crafting table.', - 'red stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'iron leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'pink stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'black dye': 'An ink sack is used as black dye in mine craft.', - 'wooden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'purple stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'detector rail': 'A detector rail can be crafted by placing a stone pressure plate in the very center square, red stone in the bottom middle square, and iron ingots in the far left and far right columns', - 'cyan wool': 'Cyan wool can be crafted by placing cyan dye next to any color wool in a crafting window.', - 'iron chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cobblestone': 'Cobblestone can be obtained by breaking stone with a pick ax.', - 'dark oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'creeper mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'carrot': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'rabbit hide': 'Rabbit hide can be randomly obtained by killing a rabbit.', - 'grass': 'When harvested with a regular shovel, grass turns into dirt. In order to obtain a grass block you will need to have a shovel with the silk touch enchant.', - 'strad disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'birch sapling': 'Birch saplings can be randomly obtained by breaking birch leaves.', - 'mossy stone': 'Mossy stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'pink dye': 'Pink dye can be crafted by placing bone meal next to rose red in a crafting window.', - 'red stone torch': 'A red stone torch is crafted by placing red stone on top of a torch in a crafting window.', - 'green stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'tall grass': 'Tall grass, which is called grass in a players inventory, spawns on grass blacks in certain biomes. Bonemeal can be used on a grass block to grow tall grass and occasionally flowers.', - 'black wool': 'Black wool can be crafted by placing an ink sac next to any color wool in a crafting window.', - 'wheat crops': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'ender pearl': 'Ender pearls can be randomly obtained by killing ender men.', - 'moss stone': 'Moss stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'fishing rod': 'A fishing rod is crafted by placing three sticks in a diagonal line, and then two string beneath the top right stick in a crafting window.', - 'bone meal': 'Bone meal can be crafted by placing a bone into a crafting window.', - 'quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'dark oak wood plank': 'Dark oak wood planks can be obtained by placing dark oak wood in a crafting table.', - 'powered rail': 'A powered rail can be crafted by placing a stick in the very center square, red stone in the bottom middle square, and gold ingots in the far left and far right columns', - 'beacon': 'A beacon can be obtained by placing a nether star in the very center square, three obsidian across the bottom row, and five glass in the remaining squares in a crafting table.', - 'blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'dark oak door': 'A Dark Oak Door can be crafted by placing six Dark Oak Planks down the first two columns.', - 'iron golem': 'An iron golem can be created by similarly to a snow golem. Place a pumpkin head on top of two iron blocks. Then place two more iron blocks on either side of the very center iron block.', - 'spruce wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'pink wool': 'Pink wool can be crafted by placing pink dye next to any color wool in a crafting window.', - 'fire charge': 'A fire charge can be crafted by placing blaze powder in the middle left square, coal in the very center square, and gunpowder in the bottom middle square in a crafting table.', - 'acacia door': 'An Acacia Door can be crafted by placing six Acacia Planks down the first two columns.', - 'iron pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chirp disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'arrow': 'An arrow can be crafted by placing flint in the top middle square, a stick in the very center square, and a feather in the bottom middle square in a crafting table.', - 'wooden ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'glass pane': 'A glass pane can be crafted by placing six glass blocks across the bottom two rows in a crafting table.', - 'gold helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'ender chest': 'An ender chest can be crafted by placing an eye of ender in the center square, and then surrounding that with eight obsidian blocks in a crafting table.', - 'light blue wool': 'Light blue wool can be crafted by placing light blue dye next to any color wool in a crafting window.', - 'string': 'String can be randomly obtained by killing spiders or by breaking cobwebs.', - 'red sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'purple wool': 'Purple wool can be crafted by placing purple dye next to any color wool in a crafting window.', - 'cyan stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'black stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'enchanted book': 'Enchanted books can be found in chests located in dungeons, strongholds, desert temples, jungle temples, and mine shafts.', - 'button': 'A button can be crafted by placing either a single piece of smooth stone or a single wooden plank in a crafting window.', - 'lime wool': 'Lime wool can be crafted by placing lime dye next to any color wool in a crafting window.', - 'coarse dirt': 'Coarse dirt can be obtained by breaking dirt in the Mega Taiga, Mesa, or Savanna biomes.', - 'ghast tear': 'Ghast tears can be rarely obtained by killing ghasts.', - 'mine cart with a furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'wheat': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'soul sand': 'Soul sand can be found commonly throughout the Nether dimension.', - 'brown mushroom': 'Brown mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'chainmail helmet': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'written book': 'A written book is created after a book and quill is signed.', - 'spruce sapling': 'Spruce saplings can be randomly obtained by breaking spruce leaves.', - 'oak sapling': 'Oak saplings can be randomly obtained by breaking oak leaves.', - 'inverted daylight sensor': 'An inverted daylight sensor can be created by right clicking on a daylight sensor.', - 'sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'red stone lamp': 'A red stone lamp can be crafted by placing glow stone in the very center square, and surrounding it with four red stone in a crafting table.', - 'crafting table': 'A crafting table is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'glow stone': 'Glow stone can be found on the ceiling in the Nether dimension.', - 'wooden pressure plate': 'A wooden pressure plate can be created by placing two wooden planks, horizontally, next to each other in a crafting window.', - 'charcoal': 'Charcoal can be obtained by burning wood blocks in a furnace.', - 'chainmail boots': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'ladder': 'A ladder is crafted by placing sticks in every square but the top middle and bottom middle square.', - 'mossy cobblestone': 'Mossy cobblestone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'golden pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'seeds': 'Wheat seeds can be randomly found by breaking tall grass.', - 'acacia fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'birch wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ward disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'music disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'enchanted golden apple': 'An enchanted golden apple is crafted by placing an apple in the very center square and surrounding it with eight gold blocks.', - 'white carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'diamonds pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chiseled red sandstone': 'Chiseled red sandstone can be crafted by placing a red sandstone slab on top of a red sandstone slab in a crafting window.', - 'stone brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'pressure plate': 'A pressure plate can be created by placing either two smooth stone or two wooden planks next to each other, horizontally, in a crafting window.', - 'jungle wood plank': 'Jungle wood planks can be obtained by placing jungle wood in a crafting table', - 'green wool': 'Green wool can be crafted by placing cactus green next to any color wool in a crafting window.', - 'sugar canes': 'Sugar canes occur naturally near water.', - 'bow': 'A bow can be crafted by placing three string in the rightmost column and then placing tree sticks in a less than sign pattern next to the string in a crafting table.', - 'lime carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'flint': 'Flint is randomly dropped while breaking gravel.', - 'black stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - }, - 'RECIPE_EN_US': { - 'snow golem': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'pillar quartz block': 'A pillar of quartz can be obtained by placing a block of quartz on top of a block of quartz in mine craft.', - 'firework rocket': 'A firework rocket can be crafted by placing a firework star in the left middle square, a piece of paper in the center square, and gunpowder in the right middle square in a crafting table. Similar to a firework star, a firework rocket can have more gunpowder added in the bottom row to increase the duration of a rocket.', - 'rabbit stew': 'Rabbit stew can be crafted by placing cooked rabbit in the top middle square, a carrot in the middle left square, a baked potato in the center square, any type of mushroom in the middle right square, and a bowl in the bottom middle square.', - 'cauldron': 'A cauldron can be created by placing iron ingots in all squares but the top middle and very center squares in a crafting table.', - 'stone shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'red carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'book and quill': 'A book and quill can be crafted by placing a book in the middle left square, an ink sac in the very center square, and a feather in the bottom middle square in a crafting table.', - 'item frame': 'An item frame can be crafted by placing leather in the very center square, and eight sticks surrounding it.', - 'map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'sticky piston': 'A sticky piston can be crafted by placing a slime ball on top of a piston in a crafting window', - 'bread': 'Bread can be crafted by placing three wheat across a row in a crafting table.', - 'wooden pick ax': 'All types of pick axs can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'shears': 'Shears can be crafted by placing two Iron Ingots diagonal from each other.', - 'raw beef': 'Raw Beef will drop from the death of a Cow or Moo shrooms.', - 'smooth red sandstone': 'Smooth red sandstone can be crafted by placing four red sandstone in a two by two grid in a crafting window.', - 'prismarine crystals': 'Prismarine Crystals can be obtained by defeating Guardians and Elder Guardians.', - 'oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'wooden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'jungle fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'activator rail': 'An activator rail can be crafted by placing a red stone torch in the very center square, sticks above and beneath it, and then six iron ingots in the remaining squares in a crafting table.', - 'farmland': 'Farmland can be created by plowing the land with a hoe.', - 'gold ore': 'Gold ore can be obtained by breaking gold ore blocks with an iron pick ax or better', - 'andesite': 'Andesite can be mined with a pick ax or crafted by placing diorite next to cobblestone in a crafting table.', - 'rose red': 'Rose red can be crafted by placing a poppy into a crafting table.', - 'iron axe': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'light blue dye': 'Light blue dye can be crafted by placing lapis lazuli next to bone meal in a crafting window.', - 'gray dye': 'Gray dye can be crafted by placing bonemeal next to an ink sac in a crafting window', - 'blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'golden leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'dark oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'wither mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'spider eye': 'A spider eye is randomly dropped by killing spiders or witches.', - 'magenta stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'brown stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'pumpkin pie': 'A pumpkin pie can be crafted by placing a pumpkin in the left middle square, sugar in the very center square, and an egg in the bottom middle square in a crafting table.', - 'snowball': 'A snowball can be obtained by breaking snow with a shovel.', - 'juke box': 'A juke box is crafted by placing a diamond in the very center square and wood planks all around that in a crafting table', - 'sand': 'Sand can be obtained by breaking sand blocks.', - 'dead bush': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'brick slab': 'A brick slab can be crafted by placing three brick blocks in a row in a crafting table.', - 'lily pad': 'Lily pads can be found naturally on water in swamplands or underground lakes.', - 'leather pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'mossy cobblestone wall': 'A mossy cobblestone wall is crafted by placing six mossy cobblestone across the bottom two rows in a crafting table.', - 'eleven disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'purple stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'magenta stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'mall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chests.', - 'jungle wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diamond ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'empty map': 'A map can be crafted by placing a compass in the middle square and eight pieces of paper surrounding it.', - 'stone pressure plate': 'A stone pressure plate can be crafted by placing two smooth stone, next to each other, horizontally, in a crafting window.', - 'trapdoor': 'Trapdoors can be crafted with either wooden planks or iron ingots. To craft a wooden trapdoor, place wooden planks in all spaces in the bottom two rows. To craft an iron trapdoor, place iron ingots in a two by two grid in a crafting table.', - 'gold boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stall disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'red stone wire': 'Redstone wire is simply red stone placed on the floor.', - 'piston': 'A piston can be crafted by placing an iron ingot in the center square, red stone in the bottom middle square, wooden planks across the top row, and cobblestone in the remaining squares.', - 'white stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'sugar': 'Sugar can be obtained by placing sugar cane in a crafting window.', - 'chain mail chest plate': 'Chain mail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'feather': 'Feathers can be randomly obtained by killing chickens.', - 'light blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'stone pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'pink carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'monster spawner': 'Monster spawners can not be obtained without cheats in mine craft.', - 'golden carrot': 'A golden carrot can be crafted by placing a carrot in the very middle square and eight gold nuggets surrounding that.', - 'stick': 'A stick can be crafted by placing a wooden plank on top of a wooden plank in a crafting window.', - 'diamond block': 'A diamond block can be crafted by placing diamonds in every square in a crafting table.', - 'green stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cooked chicken': 'Raw Chicken can be cooked by smelting it in a furnace. Alternately, Cooked Chicken has a chance of dropping when a Chicken dies while on fire.', - 'thirteen disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'wooden trapdoor': 'A wooden trapdoor can be crafted by placing wooden planks in all spaces in the bottom two rows in a crafting table.', - 'oak fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'crafting bench': 'A crafting bench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'nether quartz ore': 'Nether quartz ore can be randomly found in the nether. To obtain the ore instead of nether quartz, you will need to use a silk touch pick ax.', - 'golden sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'stone hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'coal ore': 'Coal ore can be obtained by breaking a coal ore block with a pick ax that is enchanted with silk touch', - 'dark oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 't.n.t.': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'brick': 'A brick can be crafted by smelting clay in a furnace.', - 'potato': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'orange carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'ink sack': 'An ink sack can be obtained by killing a squid.', - 'red stone': 'Redstone can be obtained by breaking red stone ore with an iron pick ax or better.', - 'dark oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'diorite': 'Diorite can be mined with a pick ax or crafted by combining cobblestone and nether quartz in a two by two grid in a crafting table.', - 'workbench': 'A workbench is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'jungle fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'magenta wool': 'Magenta wool can be crafted by placing magenta dye next to any color wool in a crafting window.', - 'dirt': 'Dirt can be obtained by breaking grass or dirt with a shovel.', - 'armor stand': 'An Armor Stand can be crafted with six sticks and one stone slab. Take three sticks and place it across the first row. Take the remaining three sticks and place one each in the bottom left, bottom right, and center middle. Place the stone slab in the bottom middle.', - 'cooked fish': 'Cooked fish is obtained by cooking fish in a furnace.', - 'lever': 'A lever can be crafted by placing a stick on top of cobblestone in a crafting window.', - 'leash': 'A leash can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'cooked rabbit': 'Cooked rabbit can be obtained by cooking raw rabbit in a furnace. Alternately, Cooked Rabbit has a chance of dropping when a Rabbit dies while on fire.', - 'jungle wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with hopper': 'A Mine cart With a Hopper can be crafted by placing a Hopper on top of a Mine cart in a crafting table.', - 'fermented spider eye': 'Fermented spider eye can be obtained by placing a brown mushroom in the middle left square, sugar in the very center square, and a spider eye in the bottom middle square in a crafting table.', - 'raw fish': 'Raw fish is randomly obtained by fishing.', - 'brown stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'sign': 'A sign is crafted by placing wooden planks in the top two rows and a stick in the bottom middle square.', - 't.n.t': 'T.N.T can be crafted by placing gunpowder in an x shape in a crafting grid and then placing sand in all remaining squares.', - 'hopper': 'A hopper can be crafted by placing a chest in the very center square, and then iron ingots in every square but the top middle, bottom left, and bottom right squares in a crafting grid.', - 'blaze rod': 'Blaze rods can be randomly obtained by killing blazes.', - 'red stone comparator': 'A red stone comparator can be crafted by placing three smooth stone across the bottom row, a nether quartz in the center square, and three red stone torches surrounding the nether quartz in a crafting table.', - 'bone': 'Bones can be obtained by killing skeletons.', - 'golden horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'golden pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'rail': 'A rail can be crafted by placing a stick in the very middle square and iron ingots vertically in both the first and last column in a crafting table.', - 'wheat seeds': 'Wheat seeds are obtained by harvesting wheat.', - 'birch fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'purple stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'golden chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'leather boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'diamond shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'leather leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sand': 'Red sand can be found in Mesa biomes.', - 'vines': 'Vines can only be harvested with shears. Vines spawn naturally in jungle trees or in swamplands.', - 'glass bottle': 'A glass bottle is crafted by creating a V shape with three glass blocks in a crafting table.', - 'red stone ore': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'emerald block': 'Emerald blocks can be crafted by placing nine emeralds in a three by three grid in a crafting table.', - 'granite': 'Granite can be mined with a pick ax or crafted by placing Diorite and a nether quartz next to each other in a crafting table.', - 'brown wool': 'Brown wool can be crafted by placing brown dye next to any color wool in a crafting window.', - 'golden apple': 'A golden apple can be crafted by placing an apple in the very center square and eight gold ingots surrounding it.', - 'birch leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'white wool': 'White wool can be crated by placing four string in a two by two grid in a crafting window. It can also be obtained by placing bone meal next to any color wool in a crafting window', - 'purple carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'hardened clay': 'Hardened clay can be crafted by smelting a clay block in a furnace.', - 'zombie mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'iron trapdoor': 'An iron trapdoor can be crafted by placing iron ingots in a two by two grid in a crafting window.', - 'flower pot': 'A flower pot is crafted by placing three bricks in a V shape in a crafting table.', - 'iron ore': 'Iron ore can be obtained by breaking iron ore blocks with a stone pick ax or better', - 'jungle wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'jungle door': 'A Jungle Door can be crafted by placing six Jungle Planks down the first two columns.', - 'golden ax': 'All types of axes can be crafted by placing three of the desired materials in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'packed ice': 'Packed ice can be found in the rare ice plains spikes biome and can only be obtained with a silk touch tool.', - 'bricks': 'Bricks can be crafted by smelting clay in a furnace.', - 'light blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'dead shrub': 'Dead bushes, also known as shrubs, can be obtained with shears.', - 'dropper': 'A dropper can be crafted by placing red stone in the middle bottom square, and cobblestone in every other square but the center one.', - 'chest': 'A chest is crafted by placing wooden planks, in every square but the middle square, in a crafting table.', - 'raw chicken': 'Raw Chicken will drop from the death of a Chicken.', - 'raw salmon': 'Raw salmon is randomly obtained by fishing.', - 'tripwire hook': 'A tripwire hook can be crafted by placing an iron ingot on top of a stick on top of a wood plank in a crafting table.', - 'oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'mine cart with command block': 'A mine cart with a command block can not be obtained without cheats.', - 'eye of ender': 'An eye of ender can be crafted by placing blaze power next to an ender pearl in a crafting window.', - 'block of coal': 'A block of coal can be crafted by placing coal in a three by three grid in a crafting window.', - 'nether star': 'A Nether Star can be obtained by defeating the Wither.', - 'gravel': 'Gravel can be obtained by breaking gravel blocks', - 'blue wool': 'Blue wool can be crafted by placing lapis lazuli next to any color wool in a crafting window.', - 'nether quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'rotten flesh': 'Rotten flesh can be randomly obtained by killing zombies.', - 'magenta carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'white stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'birch fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'carrots': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'purple dye': 'Purple dye can be crafted by placing lapis lazuli next to rose red in a crafting window.', - 'lapis lazuli block': 'A lapis lazuli block can be obtained by entirely filling a crafting table with lapis lazuli.', - 'obsidian': 'Obsidian can be mined with a diamond pick or created by placing water on top of lava. ', - 'mellohi disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music discs are found in eight percent of dungeon chests.', - 'gray wool': 'Gray wool can be crafted by placing gray dye next to any color wool in a crafting window.', - 'trapped chest': 'A trapped chest can be crafted by placing a tripwire hook next to a chest in a crafting window.', - 'light gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'iron pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'red mushroom': 'Red mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'puffer fish': 'A puffer fish can be randomly obtained by fishing.', - 'emerald': 'Emeralds can be obtained by harvesting emerald ore.', - 'wooden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'golden helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'melon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest mine carts in abandoned mine shafts.', - 'clay block': 'Clay is commonly found at the bottoms of rivers and lakes in shallow, circular patches. Clay blocks can also be found commonly in swamps.', - 'anvil': 'An anvil can be crafted by placing three blocks of iron across the top row, an iron ingot in the very center square, and then three iron ingots across the bottom row in a crafting table.', - 'daylight sensor': 'A daylight sensor can be crafted by placing three glass across the top row, three nether quartz across the middle grow, anad three wooden slabs across the bottom row in a crafting table.', - 'lead': 'A lead can be crafted by placing a slime ball in the very center, and then placing string in the top left, top middle, left middle, and bottom right squares in a crafting table.', - 'sandstone': 'Sandstone can be obtained in deserts or crafted by combining sand together in a two by two square.', - 'leather tunic': 'All chest pieces are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'black stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'lime stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mine cart with t.n.t': 'A Mine cart with T.N.T can be crafted by placing a T.N.T on top of a Mine cart in a crafting table.', - 'clock': 'A clock is crafted by placing red stone in the very center square and surrounding it with four gold ingots in a crafting table.', - 'black carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'cocoa': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'gold ingot': 'Gold ingots can be obtained by smelting gold ore in a furnace.', - 'stone brick slab': 'A stone brick slab can be crafted by placing three stone bricks in a row in a crafting table.', - 'clown fish': 'A clown fish can be randomly obtained by fishing.', - 'pumpkin seeds': 'Pumpkin seeds can be crafted by placing a pumpkin in a crafting window.', - 'mossy stone brick': 'Mossy stone brick can be crafted by placing vines next to stone bricks in a crafting window. Mossy stone brick can also be found naturally in strongholds.', - 'cobweb': 'Cobwebs can be obtained by using shears or a sword that is enchanted with silk touch', - 'milk bucket': 'A milk bucket can be obtained by right clicking on a cow with an iron bucket.', - 'iron helmet': 'All helmets are crafted by placing the desired material, in all squares but the very center square, and the bottom row, in a crafting table.', - 'yellow stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'light gray stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'diamond': 'Diamond can be obtained by breaking diamond ore with an iron pick ax or better.', - 'stone sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'cobblestone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'bed': 'A bed can be crafted by placing three wool across the top row and three wooden planks across the middle row in a crafting table.', - 'birch wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'quartz slab': 'A quartz slab can be crafted by placing three quartz blocks in a row in a crafting table.', - 'sponge': 'Sponges can be obtained by killing an elder guardian or randomly finding them in ocean monuments', - 'skeleton mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'bucket': 'A bucket can be crafted by placing three iron ingots in a V shape in a crafting table.', - 'diamond sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'golden shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'spruce wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'iron bars': 'Iron bars can be crafted by placing six iron ingots across the bottom two rows in a crafting table. Iron bars can also be found naturally in strongholds.', - 'raw rabbit': 'Raw rabbit can be randomly obtained by killing a rabbit.', - 'yellow carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'carrot on a stick': 'A carrot on a stick can be crafted by placing a fishing pole in the middle left square and a carrot in the bottom middle square in a crafting window.', - 'raw pork chop': 'A raw pork chop can be obtained by killing a pig.', - 'furnace': 'A furnace can be crafted by placing cobblestone in every square but the middle square in a crafting table.', - 'nether brick fence': 'A nether brick fence can be crafted by placing six nether brick across the bottom two rows in a crafting table.', - 'fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'diamond horse armor': 'Horse Armor can be randomly found in Dungeons, Nether fortresses, Village blacksmiths, jungle temples, desert temples, and stronghold chests.', - 'red sandstone slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'birch wood plank': 'Birch wood planks can be obtained by placing birch wood in a crafting table.', - 'bedrock': 'Bedrock can not be obtained by a player without cheats. It is the bottom most block in the game.', - 'saddle': 'Saddles can not be crafted and can only be obtained by finding them in chests inside dungeons, abandoned mine shafts, nether fortresses, desert temples, or jungle temples.', - 'light gray dye': 'Light gray dye can be crafted by placing two bone meal in a vertical row next to an ink sac in a crafting window.', - 'jungle leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'blocks disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'pumpkin': 'Pumpkins can be rarely be found on grass in most biomes.', - 'baked potato': 'A baked potato can be obtained by smelting a potato in a furnace.', - 'leather': 'Leather can be randomly obtained by killing cows or horses.', - 'light gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'end stone': 'End stone can be found naturally in the end dimension.', - 'chainmail leggings': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'rabbit\'s foot': 'A rabbit\'s foot can be obtained rarely by killing a rabbit.', - 'glass': 'Glass can be obtained by smelting sand in a furnace.', - 'stone': 'Stone can be made by smelting cobblestone in a furnace.', - 'prismarine': 'Prismarine can be crafted by placing prismarine shards in a two by two grid in a crafting window.', - 'compass': 'A compass is crafted by placing red stone in the very center square, and surrounding it with four iron ingots, in a crafting table.', - 'green stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'gold leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'command block': 'Command blocks can not be obtained without cheats in minecraft.', - 'dispenser': 'A dispenser can be created by placing a bow in the very center square, red stone right beneath that, and cobblestone in every other square.', - 'poisonous potato': 'A poisonous potato will randomly be dropped when harvesting potatoes.', - 'apple': 'Apples randomly drop from oak and dark oak leaves. They can also be randomly found in chests in strongholds or villages.', - 'red flower': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'magenta dye': 'Magenta dye can be crafted by placing purple dye next to pink dye in a crafting window.', - 'brown carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'prismarine shard': 'Prismarine Shards can be obtained by defeating Guardians and Elder Guardians.', - 'red stone block': 'A red stone block can be crafted by placing nine red stone in a three by three grid in a crafting table.', - 'yellow stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'dandelion yellow': 'Dandelion yellow is the equivalent of yellow dye in minecraft. It can be crafted by placing a dandelion or a sunflower in a crafting window.', - 'acacia wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'sandstone slab': 'A sandstone slab can be crated by placing three sandstone blocks in a row in a crafting table.', - 'gray carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished granite': 'Polished Granite can be crafted by placing four granite in a two by two grid in a crafting table.', - 'mine cart': 'A mine cart is crafted by placing five iron ingots in a U shape in a crafting table.', - 'brown stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'cyan stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'book': 'A book is crafted by creating a two by two grid where the bottom right square is leather and all other squares are paper in a crafting window.', - 'mine cart with a chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'acacia sapling': 'Acacia saplings can be randomly obtained by breaking acacia leaves.', - 'paper': 'Paper is crafted by placing three sugar cane, across a row, in a crafting table.', - 'gold chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cyan stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'mushroom stew': 'Mushroom stew is crafted by placing a red mushroom in the middle left square, a brown mushroom in the very center square, and a bowl in the bottom middle square in a crafting table.', - 'nether brick': 'Nether Brick can be mined with a pick ax, or crafted by placing four Nether Bricks in a two by two square in a crafting table.', - 'magma cream': 'Magma cream can be crafted by placing blaze powder next to a slime ball in a crafting window.', - 'snow': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'orange dye': 'Orange dye can be crafted by placing rose red next to dandelion yellow in a crafting window.', - 'potion': 'A potion is created by utilizing a brewing stand, cauldron, and water bottles.', - 'lime stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'white stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'boat': 'A boat can be obtained by making a U shape with five wooden planks.', - 'dark prismarine': 'Dark prismarine can be crafted by placing an ink sac in the very center square, and then eight placing prismarine shards around it.', - 'oak door': 'A Oak Door can be crafted by placing six Oak Planks down the first two columns.', - 'cocoa beans': 'Cocoa beans come from cocoa pods, which are naturally found in jungle biomes. Cocoa beans are used as brown dye in minecraft.', - 'oak wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'red wool': 'Red wool can be crafted by placing rose red next to any color wool in a crafting window.', - 'cooked mutton': 'Cooked mutton can be obtained by cooking raw mutton in a furnace. Alternately, one to two pieces of Cooked Mutton are dropped when a sheep dies while on fire.', - 'dark oak fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'iron door': 'An Iron Door can be crafted by placing six Iron Ingots down the first two columns.', - 'painting': 'A painting is crafted by placing wool in the very center square and surrounding it with eight sticks.', - 'spruce leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'pink stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'acacia wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'dark oak wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'chiseled sandstone': 'Chiseled sandstone can be created by placing a sandstone slab on top of a sandstone slab, in a crafting window.', - 'oak wood plank': 'Oak wood planks can be obtained by placing oak wood in a crafting table.', - 'cooked salmon': 'Cooked salmon is obtained by cooking salmon in a furnace.', - 'iron shovel': 'All types of shovels can be crafted by placing the desired material in the top middle square, and then sticks in the two squares directly beneath that in a crafting table.', - 'enchanting table': 'An enchanting table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'red stone repeater': 'A red stone repeater can be crafted by placing smooth stone in all three squares across the bottom row, red stone in the very middle square, and red stone torches on both sides of the red stone.', - 'far disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'green carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron ingot': 'Iron ingots can be obtained by smelting iron ore in a furnace.', - 'orange wool': 'Orange wool can be crafted by placing orange dye next to any color wool in a crafting window.', - 'jungle sapling': 'Jungle saplings can be randomly obtained by breaking jungle leaves.', - 'stone slab': 'A stone slab can be crafted by placing three stone blocks in a row in a crafting table.', - 'light blue stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'cyan dye': 'Cyan dye can be crafted by placing lapis lazuli next to cactus green in a crafting window.', - 'steak': 'Raw Beef can be cooked into Steak by smelting it in a furnace. Alternately, Steak has a chance of dropping when a Cow or Moo shroom dies while on fire.', - 'orange stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'blue stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'spruce fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'coal': 'Coal can be obtained by breaking a coal ore block with a wooden pick ax or better.', - 'potatoes': 'Potatoes can be rarely obtained by killing zombies or, they can be found as crops in villages.', - 'light gray stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'egg': 'Eggs are randomly produced by chickens. Throwing an egg has a chance to create a new chicken.', - 'spruce wood plank': 'Spruce wood planks can be obtained by placing spruce wood in a crafting table.', - 'orange stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'acacia wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'light gray wool': 'Light gray wool can be crafted by placing light gray dye next to any color wool in a crafting window.', - 'hay bale': 'A hay bale can be crafted by placing wheat in a three by three grid in a crafting table.', - 'clay': 'Clay is obtained by breaking clay blocks with a non silk touch tool.', - 'bowl': 'A bowl can be crafted by placing three wooden planks in a v shape in a crafting table.', - 'leather helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table/', - 'pink stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'diamond chest plate': 'All chest plates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'gray stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'yellow stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'snowman': 'A snow golem can be created by placing a pumpkin on top of two snow blocks on the ground.', - 'diamond ore': 'Diamond ore can be found in the bottom sixteen layers on the map. One can break diamond ore with an iron pick ax or better. This will cause the diamond ore to break into a diamond. To obtain the ore, you will need to use a pick ax with the silk touch enchant.', - 'banner': 'A Banner can be crafted by placing six wool across the top two rows, then placing a stick on the bottom middle. The banner will take on the color of the wool you choose.', - 'stone ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'firework star': 'A firework star can be crafted by placing gunpower in the middle left square and any color dye in the center square in a crafting table. A firework star can also be crafted with optional ingredients such as diamonds, glow stone dust, or feathers, that are placed directly beneath the dye in a crafting table.', - 'nether wart': 'Nether warts can be naturally found in nether fortresses as a plant.', - 'red stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'quartz block': 'A quartz block can be crafted by placing four nether quartz in a two by two grid in a crafting table.', - 'poppy': 'Poppies can be found naturally on grass or created randomly by using bone meal on grass.', - 'acacia fence': 'Any type of fence can be crafted by putting a wooden plank, a stick, and then another wooden plank in the bottom two rows of a crafting table.', - 'cactus': 'Cactus can be found naturally in desert biomes. ', - 'spruce door': 'A Spruce Door can be crafted by placing six Spruce Planks down the first two columns.', - 'cat disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'flint and steel': 'Flint and steel can be crafted by placing an iron ingot to the left of flint in a crafting window.', - 'gold pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'slime ball': 'Slime balls are randomly dropped by killing slimes.', - 'cooked porkchop': 'A cooked porkchop can be obtained by cooking a raw porkchop in a furnace or by lighting a pig on fire.', - 'polished andesite': 'Polished Andesite can be crafted by placing four andesite in a two by two grid in a crafting table.', - 'prismarine bricks': 'Prismarine bricks can be crafted by placing prismarine shards in a three by three grid in a crafting table.', - 'wither': 'A wither can be created by placing three wither skulls on top of soul sand that is placed on the ground in a T shape.', - 'lime dye': 'Lime dye can be crafted by placing cactus green next to bone meal in a crafting window.', - 'blue carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'door': 'A door can be crafted by placing six Planks, down the first two columns, in a crafting table.', - 'tripwire': 'Tripwire is simply string next to a tripwire hook.', - 'enchantment table': 'An enchantment table can be crafted by placing a book in the top middle square, diamonds in the middle left and middle right squares, and obsidian in the very center and across the bottom row, in a crafting table.', - 'cyan carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'polished diorite': 'Polished Diorite can be crafted by placing four diorite in a two by two grid in a crafting table.', - 'golden boots': 'All boots are crafted by placing the desired material in the middle left, bottom left, middle right, and bottom right squares of a crafting table.', - 'iron block': 'An iron block can be crafted by placing iron ingots in a three by three grid in a crafting table.', - 'acacia leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'dark oak sapling': 'Dark oak saplings can be randomly obtained by breaking dark oak leaves', - 'diamond hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'dandelion': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'lapis lazuli': 'Can be obtained by breaking lapis lazuli ore with a stone pick ax or better', - 'sugar cane': 'Sugar cane can be found naturally near water,', - 'birch door': 'A Birch Door can be crafted by placing six Birch Planks down the first two columns.', - 'cactus green': 'Cactus green can be crafted by smelting a cactus in a furnace.', - 'gold block': 'A gold block can be crafted by placing gold ingots in a three by three grid in a crafting table.', - 'smooth sandstone': 'Smooth sandstone can be created by placing sandstone in a two by two grid in a crafting window', - 'magenta stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'note block': 'A note block is crafted by placing red stone in the very center square and wooden planks all around that in a crafting table', - 'snow block': 'Snow can be crafted by placing snowballs in a two by two grid in a crafting window.', - 'mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'diamond leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'red sandstone': 'Red sandstone can be crafted by placing four red sand in a two by two grid in a crafting window.', - 'orange stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'slime block': 'A slime block can be crafted by placing slime balls in a three by three grid in a crafting window.', - 'bookshelf': 'A bookshelf is crafted by placing books across the middle row and wooden planks across the top and bottom rows', - 'cake': 'Cake can be crafted by placing three buckets of milk across the top row, sugar in the left middle, and right middle squares, an egg in the very center square, and three wheat across the bottom squares in a crafting table.', - 'wooden button': 'A wooden button can be crafted by placing a single wooden plank in a crafting window.', - 'chiseled quartz block': 'A chiseled quartz block can be obtained by placing a quartz slab on top of a quartz slab in a crafting table.', - 'stone button': 'A stone button can be crafted by placing a single piece of smooth stone in a crafting window.', - 'glow stone dust': 'Glow stone dust is obtained by breaking glow stone blocks.', - 'lime stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'cobblestone wall': 'A cobblestone wall is crafted by placing six cobblestone across the bottom two rows in a crafting table.', - 'name tag': 'Name Tags can only be obtained in three ways. The first way is by finding it in a Dungeon chest. The second way is by fishing. The last way Name Tags can be obtained is by trading with the Librarian Villagers for twenty to twenty two Emeralds.', - 'gunpowder': 'Gunpowder can be randomly obtained by killing creepers.', - 'blaze powder': 'Blaze powder can be obtained by placing a blaze row in a crafting window.', - 'brewing stand': 'A brewing stand can be crafted by placing a blaze rod in the center square, and three cobblestone across the bottom row in a crafting table.', - 'torch': 'A torch can be crafted by placing a piece of coal on top of a stick.', - 'yellow wool': 'Yellow wool can be crafted by placing dandelion yellow next to any color wool in a crafting window.', - 'watermelon': 'A melon can be found naturally in jungles or can be grown from melon seeds found in chest minecarts in abandoned mine shafts.', - 'wait disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'glistering melon': 'A glistering melon can be crafted by placing a melon in the very center square and surrounding it with eight gold nuggets in a crafting table.', - 'netherrack': 'Netherrack can be found commonly throughout the Nether dimension.', - 'leather chest plate': 'All chest places are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'wooden slab': 'A wooden slab can be crafted by placing three wooden planks in a row in a crafting table.', - 'nether brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ice': 'Ice can be found naturally in snow biomes. If broken, or placed near a heat source, ice will turn into water. To obtain an ice block, one would need to mine it with a silk touch pick ax.', - 'large fern': 'Large ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'nether brick slab': 'A nether brick slab can be crafted by placing three nether brick in a row in a crafting table.', - 'spruce wood slab': 'All types of slabs can be crafted by placing three of the desired materials across a row in a crafting table.', - 'iron hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'fern': 'Ferns are naturally found in jungle, taiga, and mega taiga biomes.', - 'sea lantern': 'A sea lantern can be crafted by placing prismarine shards in the four corners of a crafting table, and then placing prismarine crystals in every other square.', - 'cookie': 'A cookie can be crafted by placing wheat, horizontally, on both sides of cocoa beans in a crafting table.', - 'melon seeds': 'Melon seeds can be crafted by placing a slice of melon in a crafting window.', - 'gold nugget': 'A gold nugget can be crafted by placing a single gold ingot into a crafting window. They can also be randomly obtained by killing a zombie pig men.', - 'red stone ore block': 'Redstone ore can be found in the bottom sixteen layers on the map. If broken with an iron pick ax or better, it will drop some amount of red stone. To obtain the ore itself, one would need to use a pick ax with a silk touch enchant.', - 'diamond helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'spruce fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'golden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'acacia wood plank': 'Acacia wood planks can be obtained by placing acacia wood in a crafting table', - 'diamond pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'lapis lazuli ore': 'Lapis Lazuli Ore can be only be obtained by using a pick ax with the silk touch enchant.', - 'raw mutton': 'Raw mutton can be obtained by killing a sheep.', - 'quartz stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'brick block': 'A brick block can be crafted by placing clay bricks in a two by two grid in a crafting window.', - 'cobblestone slab': 'A cobblestone slab can be crafted by placing three cobblestone blocks in a row in a crafting table.', - 'emerald ore': 'Emerald ore can only be found in extreme hills biomes between layers four and thirty-two. It can be mined with an iron pick ax or better to obtain an emerald. To obtain the ore itself, you will need a silk touch pick ax.', - 'yellow flower': 'Dandelions can be found naturally on grass or created randomly by using bone meal on grass.', - 'jack o\'lantern': 'A jack o\'lantern can be crafted by placing a pumpkin on top of a torch in a crafting table.', - 'red stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'iron leggings': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'pink stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'black dye': 'An ink sack is used as black dye in mine craft.', - 'wooden hoe': 'All types of hoes can be crafted by placing two of the desired material in the top left, and top middle squares, with sticks in the center and bottom middle squares in a crafting table.', - 'purple stained glass': 'Any type of stained glass can be crafted by placing the desired color dye in the center square, and glass surrounding that.', - 'mine cart with chest': 'A mine cart with a chest is crafted by placing a chest on top of a mine cart in a crafting window.', - 'detector rail': 'A detector rail can be crafted by placing a stone pressure plate in the very center square, red stone in the bottom middle square, and iron ingots in the far left and far right columns', - 'cyan wool': 'Cyan wool can be crafted by placing cyan dye next to any color wool in a crafting window.', - 'iron chestplate': 'All chestplates are crafted by placing the desired material in all squares but the top middle square in a crafting table.', - 'cobblestone': 'Cobblestone can be obtained by breaking stone with a pick ax.', - 'dark oak wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares.', - 'creeper mob head': 'Mob heads can be obtained by having a charged creeper blow up the mob whose head you want to obtain.', - 'carrot': 'Carrots can be rarely obtained by killing zombies or, they can be naturally found as crops in villages.', - 'rabbit hide': 'Rabbit hide can be randomly obtained by killing a rabbit.', - 'grass': 'When harvested with a regular shovel, grass turns into dirt. In order to obtain a grass block you will need to have a shovel with the silk touch enchant.', - 'strad disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'birch sapling': 'Birch saplings can be randomly obtained by breaking birch leaves.', - 'mossy stone': 'Mossy stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'pink dye': 'Pink dye can be crafted by placing bone meal next to rose red in a crafting window.', - 'red stone torch': 'A red stone torch is crafted by placing red stone on top of a torch in a crafting window.', - 'green stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'tall grass': 'Tall grass, which is called grass in a players inventory, spawns on grass blacks in certain biomes. Bonemeal can be used on a grass block to grow tall grass and occasionally flowers.', - 'black wool': 'Black wool can be crafted by placing an ink sac next to any color wool in a crafting window.', - 'wheat crops': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'ender pearl': 'Ender pearls can be randomly obtained by killing ender men.', - 'moss stone': 'Moss stone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'fishing rod': 'A fishing rod is crafted by placing three sticks in a diagonal line, and then two string beneath the top right stick in a crafting window.', - 'bone meal': 'Bone meal can be crafted by placing a bone into a crafting window.', - 'quartz': 'Nether Quartz can be obtained by smelting Nether Quartz Ore in a furnace.', - 'dark oak wood plank': 'Dark oak wood planks can be obtained by placing dark oak wood in a crafting table.', - 'powered rail': 'A powered rail can be crafted by placing a stick in the very center square, red stone in the bottom middle square, and gold ingots in the far left and far right columns', - 'beacon': 'A beacon can be obtained by placing a nether star in the very center square, three obsidian across the bottom row, and five glass in the remaining squares in a crafting table.', - 'blue stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'dark oak door': 'A Dark Oak Door can be crafted by placing six Dark Oak Planks down the first two columns.', - 'iron golem': 'An iron golem can be created by similarly to a snow golem. Place a pumpkin head on top of two iron blocks. Then place two more iron blocks on either side of the very center iron block.', - 'spruce wood': 'All types of wood can be obtained by breaking the tree they naturally grow into.', - 'pink wool': 'Pink wool can be crafted by placing pink dye next to any color wool in a crafting window.', - 'fire charge': 'A fire charge can be crafted by placing blaze powder in the middle left square, coal in the very center square, and gunpowder in the bottom middle square in a crafting table.', - 'acacia door': 'An Acacia Door can be crafted by placing six Acacia Planks down the first two columns.', - 'iron pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chirp disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'oak leaves': 'All leaves can be obtained by using a shear on the desired leaf.', - 'arrow': 'An arrow can be crafted by placing flint in the top middle square, a stick in the very center square, and a feather in the bottom middle square in a crafting table.', - 'wooden ax': 'All types of axes can be crafted by placing three of the desired material in the top left, top middle, and middle left squares, with sticks in the center and bottom middle squares in a crafting table.', - 'glass pane': 'A glass pane can be crafted by placing six glass blocks across the bottom two rows in a crafting table.', - 'gold helmet': 'All helmets are crafted by placing the desired material in all squares but the very center square and the bottom row in a crafting table.', - 'ender chest': 'An ender chest can be crafted by placing an eye of ender in the center square, and then surrounding that with eight obsidian blocks in a crafting table.', - 'light blue wool': 'Light blue wool can be crafted by placing light blue dye next to any color wool in a crafting window.', - 'string': 'String can be randomly obtained by killing spiders or by breaking cobwebs.', - 'red sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'purple wool': 'Purple wool can be crafted by placing purple dye next to any color wool in a crafting window.', - 'cyan stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - 'black stained clay': 'Any type of stained clay can be crafted by placing the appropriate dye in the center square and hardened clay surrounding it.', - 'enchanted book': 'Enchanted books can be found in chests located in dungeons, strongholds, desert temples, jungle temples, and mine shafts.', - 'button': 'A button can be crafted by placing either a single piece of smooth stone or a single wooden plank in a crafting window.', - 'lime wool': 'Lime wool can be crafted by placing lime dye next to any color wool in a crafting window.', - 'coarse dirt': 'Coarse dirt can be obtained by breaking dirt in the Mega Taiga, Mesa, or Savanna biomes.', - 'ghast tear': 'Ghast tears can be rarely obtained by killing ghasts.', - 'mine cart with a furnace': 'A mine cart with a furnace is crafted by placing a furnace on top of a mine cart in a crafting window.', - 'wheat': 'Wheat can be found naturally in villages or can be grown from seeds that one can obtain by breaking tall grass.', - 'soul sand': 'Soul sand can be found commonly throughout the Nether dimension.', - 'brown mushroom': 'Brown mushrooms can be found naturally in darkly lit areas, mushroom biomes, or the nether.', - 'chainmail helmet': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'written book': 'A written book is created after a book and quill is signed.', - 'spruce sapling': 'Spruce saplings can be randomly obtained by breaking spruce leaves.', - 'oak sapling': 'Oak saplings can be randomly obtained by breaking oak leaves.', - 'inverted daylight sensor': 'An inverted daylight sensor can be created by right clicking on a daylight sensor.', - 'sandstone stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'red stone lamp': 'A red stone lamp can be crafted by placing glow stone in the very center square, and surrounding it with four red stone in a crafting table.', - 'crafting table': 'A crafting table is crafted by placing wooden planks in a two by two grid in a crafting window.', - 'glow stone': 'Glow stone can be found on the ceiling in the Nether dimension.', - 'wooden pressure plate': 'A wooden pressure plate can be created by placing two wooden planks, horizontally, next to each other in a crafting window.', - 'charcoal': 'Charcoal can be obtained by burning wood blocks in a furnace.', - 'chainmail boots': 'Chainmail armor can only be obtained by trading with a villager or getting a rare drop off of a mob.', - 'ladder': 'A ladder is crafted by placing sticks in every square but the top middle and bottom middle square.', - 'mossy cobblestone': 'Mossy cobblestone can be crafted by placing vines next to cobblestone in a crafting table. It can also be found naturally in various dungeons.', - 'golden pick ax': 'All types of pick axes can be crafted by placing three of the desired material across the top row, and then placing sticks in the center and bottom middle squares in a crafting table.', - 'seeds': 'Wheat seeds can be randomly found by breaking tall grass.', - 'acacia fence gate': 'Any type of fence gate can be crafted by placing a stick, a wooden plank, and then another stick across the bottom two rows in a crafting table.', - 'birch wood stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'ward disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'music disc': 'A random music disc has a possibility of dropping when a Skeleton\'s Arrow kills a Creeper. Alternately, music disc are found in eight percent of dungeon chest.', - 'enchanted golden apple': 'An enchanted golden apple is crafted by placing an apple in the very center square and surrounding it with eight gold blocks.', - 'white carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'iron sword': 'All types of swords can be crafted by placing the desired material in the top middle and very center square, with a stick beneath them, in a crafting table', - 'diamonds pants': 'All leggings are crafted by placing the desired material in all squares but the center square and bottom middle square in a crafting table.', - 'chiseled red sandstone': 'Chiseled red sandstone can be crafted by placing a red sandstone slab on top of a red sandstone slab in a crafting window.', - 'stone brick stairs': 'All types of stairs can be crafted by placing the desired material in all squares but the top middle, top right, and middle right squares in a crafting table.', - 'pressure plate': 'A pressure plate can be created by placing either two smooth stone or two wooden planks next to each other, horizontally, in a crafting window.', - 'jungle wood plank': 'Jungle wood planks can be obtained by placing jungle wood in a crafting table', - 'green wool': 'Green wool can be crafted by placing cactus green next to any color wool in a crafting window.', - 'sugar canes': 'Sugar canes occur naturally near water.', - 'bow': 'A bow can be crafted by placing three string in the rightmost column and then placing tree sticks in a less than sign pattern next to the string in a crafting table.', - 'lime carpet': 'Any type of carpet can be crafted by placing two wool, of the same color, next to each other in a crafting window.', - 'flint': 'Flint is randomly dropped while breaking gravel.', - 'black stained glass pane': 'Any type of stained glass pane can be crafted by placing the same color stained glass, horizontally, in the bottom two rows.', - }, - 'RECIPE_DE_DE': { - 'schneegolem': 'Ein Schneegolem kann erschaffen werden, indem ein Kürbis auf zwei auf dem Boden stehende Schneeblöcke gesetzt wird.', - 'quarzsäule': 'Eine Quarzsäule erhält man, indem in Minecraft ein Quarzblock auf einem Quarzblock platziert wird.', - 'feuerwerksrakete': 'Eine Feuerwerksrakete kann gecraftet werden, indem ein Feuerwerksstern in das linke mittlere Feld, ein Blatt Papier in das mittlere Feld und Schwarzpulver in das rechte mittlere Feld der Werkbank gelegt wird. Ähnlich wie bei einem Feuerwerksstern kann einer Feuerwerksrakete in der unteren Reihe zusätzliches Schwarzpulver hinzugefügt werden, um die Dauer der Rakete zu verlängern.', - 'kaninchenragout': 'Kaninchenragout kann gecraftet werden, indem ein Gekochtes Kaninchen in das obere mittlere Feld, eine Karotte in das linke mittlere Feld, eine Ofenkartoffel in das Feld ganz in der Mitte, eine beliebige Pilzart in das rechte mittlere Feld und eine Schüssel in des untere mittlere Feld platziert wird.', - 'kessel': 'Ein Kessel kann hergestellt werden, indem Eisenbarren in alle Felder der Werkbank mit Ausnahme des oberen mittleren Feldes und des Feldes ganz in der Mitte gelegt werden.', - 'steinschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'roter teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'buch und feder': 'Buch und Feder kann gecraftet werden, indem in der Werkbank ein Buch in das linke mittlere Feld, ein Tintenbeutel in das Feld ganz in der Mitte und eine Feder in das untere mittlere Feld platziert werden.', - 'rahmen': 'Ein Rahmen kann gecraftet werden, indem Leder in das Feld ganz in der Mitte platziert und dann von acht Stöcken umgeben wird.', - 'karte': 'Eine Karte kann gecraftet werden, indem ein Kompass in das Feld ganz in der Mitte platziert und dann von acht Blättern Papier umgeben wird.', - 'klebriger Kolben': 'Ein klebriger Kolben kann gecraftet werden, indem ein Schleimball im Craftingfeld über einem Kolben platziert wird.', - 'brot': 'Brot kann gecraftet werden, indem eine Reihe der Werkbank vollständig mit Weizen gefüllt wird.', - 'holzspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'schere': 'Eine Schere kann gecraftet werden, indem zwei Eisenbarren diagonal zueinander platziert werden.', - 'rohes rindfleisch': 'Rohes Rindfleisch wird beim Tod einer Kuh oder Mooshroom gedroppt.', - 'glatter roter sandstein': 'Glatter roter Sandstein kann gecraftet werden, indem im Craftingfeld vier rote Sandsteinblöcke in einem 2x2-Raster platziert werden.', - 'prismarinkristalle': 'Prismarinkristalle erhält man, indem Wächter und große Wächter besiegt werden.', - 'eichenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'holzschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'treppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'tropenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'aktivierungsschiene': 'Eine Aktivierungsschiene kann gecraftet werden, indem eine Redstone-Fackel in das Feld ganz in der Mitte, Stöcke darüber und darunter und dann sechs Eisenbarren in den übrigen Feldern der Werkbank platziert werden.', - 'ackerboden': 'Ackerboden kann hergestellt werden, indem der Boden mit einer Hacke bearbeitet wird.', - 'golderz': 'Golderz erhält man, indem Golderzblöcke mit einer Spitzhacke aus Eisen oder einem hochwertigerem Material abgebaut werden.', - 'andesit': 'Andesit kann mit einer Spitzhacke abgebaut werden, oder es lässt sich craften, indem in der Werkbank Diorit neben Bruchstein platziert wird.', - 'roter farbstoff': 'Roter Farbstoff kann gecraftet werden, indem eine Mohnblume in die Werkbank gelegt wird.', - 'eisenaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'hellblauer farbstoff': 'Hellblauer Farbstoff kann gecraftet werden, indem im Craftingfeld Lapislazuli neben Knochenmehl platziert wird.', - 'grauer farbstoff': 'Grauer Farbstoff kann gecraftet werden, indem im Craftingfeld Knochenmehl neben einem Tintenbeutel platziert wird.', - 'blau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'eiserne pferderüstung': 'Eine Pferderüstung kann zufällig in Verliesen, Netherfestungen, bei Schmieden, in Dschungeltempeln, Wüstentempeln und Truhen in Festungen gefunden werden.', - 'rot gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'ziegeltreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'goldene hose': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'schwarzeichenzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'witherschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'spinnenauge': 'Ein Spinnenauge droppt zufällig beim Töten von Spinnen oder Hexen.', - 'magenta gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'braun gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'kürbiskuchen': 'Ein Kürbiskuchen kann gecraftet werden, indem in der Werkbank ein Kürbis in das linke mittlere Feld, Zucker in das Feld ganz in der Mitte und ein Ei in das untere mittlere Feld platziert werden.', - 'schneeball': 'Einen Schneeball erhält man, indem Schnee mit einer Schaufel zerkleinert wird.', - 'jukebox': 'Eine Jukebox wird hergestellt, indem ein Diamant in einer Werkbank im mittleren Feld platziert und von Holzbrettern umgeben wird.', - 'sand': 'Sand erhält man, indem Sandblöcke zerkleinert werden.', - 'toter busch': 'Tote Büsche, auch nur Büsche genannt, werden mit einer Schere erhalten.', - 'ziegelstufe': 'Eine Ziegelstufe kann hergestellt werden, indem in einer Werkbank drei Ziegelstein-Blöcke in einer Reihe platziert werden.', - 'seerosenblatt': 'Seerosenblätter kommen natürlich auf Wasser in Sümpfen oder unterirdischen Seen vor.', - 'lederhose': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'bemooste bruchsteinmauer': 'Eine Bemooste Bruchsteinmauer wird gecraftet, indem sechs Bemooste Bruchsteine in die beiden unteren Reihen einer Werkbank platziert werden.', - 'schallplatte 11': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'violett gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'magenta gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'schallplatte mall': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'tropenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'diamantaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'leere karte': 'Eine Karte kann gecraftet werden, indem ein Kompass in das Feld ganz in der Mitte platziert und dann von acht Blättern Papier umgeben wird.', - 'steindruckplatte': 'Eine Steindruckplatte lässt sich craften, indem zwei glatte Steine horizontal nebeneinander in das Craftingfeld gelegt werden.', - 'falltür': 'Falltüren können entweder mit Holzbrettern oder Eisenbarren gecraftet werden. Um eine Holzfalltür zu craften, werden Holzbretter in alle Felder der beiden unteren Reihen platziert. Um eine Eisenfalltür zu craften, werden Eisenbarren in einem 2x2-Raster in einer Werkbank platziert.', - 'goldstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'schallplatte stall': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'redstone-kabel': 'Das Redstone-Kabel ist einfach Redstone, das auf dem Boden platziert wird.', - 'kolben': 'Ein Kolben kann gecraftet werden, indem ein Eisenbarren im Feld ganz in der Mitte, Redstone im unteren mittleren Feld, Holzbretter in allen Felder der oberen Reihe und Bruchstein in den übrigen Feldern platziert werden.', - 'weiß gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'antriebslore': 'Eine Antriebslore wird gecraftet, indem ein Ofen in einem Craftingfeld über einer Lore platziert wird.', - 'zucker': 'Zucker kann erhalten werden, indem Zuckerrohr in einer Werkbank platziert wird.', - 'kettenhemd': 'Kettenrüstung kann nur durch den Handel mit einem Dorfbewohner oder einem seltenen Drop von einer Kreatur erhalten werden.', - 'feder': 'Federn können zufällig durch das Töten von Hühnern erhalten werden.', - 'hellblau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'eichenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'steinspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'rosa teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'monsterspawner': 'Monsterspawner können in Minecraft nur durch Cheats erhalten werden.', - 'goldene karotte': 'Eine Goldene Karotte kann gecraftet werden, indem eine Karotte in das Feld ganz in der Mitte gelegt und dann von acht Goldklumpen umgeben wird.', - 'stock': 'Ein Stock kann gecraftet werden, indem in einem Craftingfeld ein Holzbrett über einem Holzbrett platziert wird.', - 'diamantblock': 'Ein Diamantblock kann gecraftet werden, indem Diamanten in allen Feldern einer Werkbank platziert werden.', - 'grün gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'gebratenes hühnchen': 'Rohes Hühnchen kann gebraten werden, indem es in einem Ofen geschmolzen wird. Alternativ dazu besteht die Chance, dass Gebratenes Hühnchen droppt, wenn ein brennendes Huhn stirbt.', - 'schallplatte 13': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'holzfalltür': 'Eine Holzfalltür wird gecraftet, indem Holzbretter in einer Werkbank in alle Felder der beiden unteren Reihen platziert werden.', - 'eichenzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'werkbank': 'Eine Werkbank kann gecraftet werden, indem Holzbretter in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'netherquarzerz': 'Netherquarzerz kann zufällig im Nether gefunden werden. Um das Erz anstelle von Netherquarz zu erhalten, muss eine mit Behutsamkeit verzauberte Spitzhacke verwendet werden.', - 'goldschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'grau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'hellblau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'diamantstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'steinhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'steinkohle': 'Steinkohle erhält man, indem Steinkohleblöcke mit einer mit Behutsamkeit verzauberten Spitzhacke abgebaut werden.', - 'schwarzeichenlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'tnt': 'TNT kann gecraftet werden, indem in einem Craftingfeld Schwarzpulver X-förmig platziert und dann Sand in alle übrigen Felder gelegt wird.', - 'ziegel': 'Ein Ziegel kann gecraftet werden, indem Ton in einem Ofen geschmolzen wird.', - 'kartoffel': 'Kartoffeln können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'oranger teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'tintenbeutel': 'Ein Tintenbeutel kann durch das Töten eines Tintenfischs erhalten werden.', - 'redstone': 'Redstone erhält man, indem Redstonerz mit einer Spitzhacke aus Eisen oder einem hochwertigerem Material abgebaut wird.', - 'schwarzeichenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'diorit': 'Diorit kann mit einer Spitzhacke abgebaut oder gecraftet werden, indem in der Werkbank in einem 2x2-Raster Bruchstein mit Netherquarz kombiniert wird.', - 'grau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'tropenholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'magenta wolle': 'Magenta Wolle kann gecraftet werden, indem in einem Craftingfeld Magenta Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'erde': 'Erde erhält man, indem Gras oder Erde mit einer Schaufel zerkleinert wird.', - 'rüstungsständer': 'Ein Rüstungsständer kann mit sechs Stöcken und einer Steinstufe gecraftet werden. Drei Stöcke werden in der obersten Reihe platziert. Die übrigen drei Stöcke werden jeweils im unteren linken und unteren rechten Feld sowie im Feld ganz in der Mitte platziert. Die Steinstufe wird wird im unteren mittleren Feld platziert.', - 'gebratener fisch': 'Gebratener Fisch wird erhalten, indem Fisch in einem Ofen gebraten wird.', - 'hebel': 'Ein Hebel kann gecraftet werden, indem in einem Craftingfeld ein Stock über Bruchstein platziert wird.', - 'leine': 'Eine Leine kann gecraftet werden, indem ein Schleimball in einer Werkbank in das Feld ganz in der Mitte und dann Fäden in das obere linke, obere mittlere, mittlere linke und untere rechte Feld platziert werden.', - 'gebratenes kaninchen': 'Gebratenes Kaninchen wird erhalten, indem Rohes Kaninchen in einem Ofen gebraten wird. Alternativ dazu besteht die Chance, dass Gebratenes Kaninchen droppt, wenn ein brennendes Kaninchen stirbt.', - 'tropenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'trichterlore': 'Eine Trichterlore wird gecraftet, indem ein Trichter in einer Werkbank über einer Lore platziert wird.', - 'fermentiertes Spinnenauge': 'Fermentiertes Spinnenauge kann gecraftet werden, indem in einer Werkbank ein brauner Pilz im mittleren linken Feld, Zucker im Feld ganz in der Mitte und ein Spinnenauge im unteren mittleren Feld platziert werden.', - 'roher fisch': 'Roher Fisch kann zufällig durch Angeln erhalten werden.', - 'braun gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'schild': 'Ein Schild kann gecraftet werden, indem Holzbretter in den beiden oberen Reihen und ein Stock im unteren mittleren Feld platziert werden.', - 'trichter': 'Ein Trichter kann gecraftet werden, indem in einer Werkbank eine Truhe im Feld ganz in der Mitte und dann Eisenbarren in jedem Feld mit Ausnahme des oberen mittleren, des linken unteren und rechten unteren Feldes platziert werden.', - 'lohenrute': 'Lohenruten können zufällig durch das Töten von Lohen erhalten werden.', - 'redstone-komparator': 'Ein Redstone-Komparator kann gecraftet werden, indem in der Werkbank drei glatte Steine in der unteren Reihe, ein Netzerquarz im Feld ganz in der Mitte und drei Redstone-Fackeln um den Netzerquarz herum platziert werden.', - 'knochen': 'Knochen können durch das Töten von Skeletten erhalten werden.', - 'goldene pferderüstung': 'Eine Pferderüstung kann zufällig in Verliesen, Netherfestungen, bei Schmieden, in Dschungeltempeln, Wüstentempeln und Truhen in Festungen gefunden werden.', - 'goldbeinschutz': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'schiene': 'Eine Schiene kann gecraftet werden, indem in einer Werkbank ein Stock im Feld ganz in der Mitte und Eisenbarren senkrecht in der ersten und letzten Spalte platziert werden.', - 'weizenkörner': 'Weizenkörner können durch die Ernte von Weizen erhalten werden.', - 'birkenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'violett gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'goldharnisch': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'lederstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'diamantschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'roter sand': 'Roter Sand kann in Tafelberg-Biomen gefunden werden.', - 'ranken': 'Ranken können nur mit einer Schere geerntet werden. Ranken wachsen natürlich an Dschungelbäumen oder in Sümpfen.', - 'glasflasche': 'Eine Glasflasche kann gecraftet werden, indem in einer Werkbank mit drei Glasblöcken ein V geformt wird.', - 'redstone-erz': 'Redstone-Erz kann in den unteren sechzehn Schichten der Karte gefunden werden. Wenn es mit einer Eisenspitzhacke oder einer Spitzhacke aus hochwertigerem Material zerstört wird, droppt es eine gewisse Anzahl von Redstone. Um das Erz an und für sich zu erhalten, muss eine Spitzhacke mit der Verzauberung Behutsamkeit verwendet werden.', - 'smaragdblock': 'Ein Smaragdblock kann gecraftet werden, indem neun Smaragde in einem 3x3-Raster in einer Werkbank platziert werden.', - 'granit': 'Granit kann mit einer Spitzhacke abgebaut oder gecraftet werden, indem in der Werkbank Diorit und ein Netherquarz nebeneinander platziert werden.', - 'braune wolle': 'Braune Wolle kann gecraftet werden, indem in einem Craftingfeld Brauner Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'goldener apfel': 'Ein Goldener Apfel kann gecraftet werden, indem ein Apfel in das Feld ganz in der Mitte gelegt und dann von acht Goldbarren umgeben wird.', - 'birkenlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'weiße wolle': 'Weiße Wolle kann gecraftet werden, indem im Craftingfeld vier Fäden in einem 2x2-Raster platziert werden. Sie kann auch gecraftet werden, indem in einem Craftingfeld Knochenmehl neben Wolle einer beliebigen Farbe platziert wird.', - 'violetter teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'gebrannter ton': 'Gebrannter Ton kann gecraftet werden, indem ein Tonblock in einem Ofen geschmolzen wird.', - 'zombieschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'eisenfalltür': 'Eine Eisenfalltür kann gecraftet werden, indem Eisenbarren in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'blumentopf': 'Ein Blumentopf kann gecraftet werden, indem in einer Werkbank drei Ziegel in V-Form platziert werden.', - 'eisenerz': 'Eisenerz kann erhalten werden, indem Eisenerzblöcke mit einer Spitzhacke aus Stein oder einem hochwertigerem Material abgebaut werden.', - 'tropenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'birkenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'tropenholztür': 'Eine Tropenholztür kann gecraftet werden, indem sechs Tropenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'goldaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'packeis': 'Packeis kann in der seltenen Eiszapfentundra gefunden und nur mit einem Werkzeug mit der Verzauberung Behutsamkeit abgebaut werden.', - 'hellblauer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'spender': 'Ein Spender kann gecraftet werden, indem Redstone im mittleren unteren Feld und Bruchstein in den übrigen Feldern außer im Feld ganz in der Mitte platziert werden.', - 'truhe': 'Eine Truhe kann gecraftet werden, indem Holzbretter in alle Felder einer Werkbank mit Ausnahme des Feldes ganz in der Mitte platziert werden.', - 'rohes hühnchen': 'Rohes Hühnchen wird beim Tod eines Huhns gedroppt.', - 'roher lachs': 'Roher Lachs kann zufällig durch Angeln erhalten werden.', - 'haken': 'Ein Haken kann gecraftet werden, indem in einer Werkbank ein Eisenbarren über einem Stock über einem Holzbrett platziert wird.', - 'eichenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'befehlsblocklore': 'Eine Befehlsblocklore kann nur durch Cheats erhalten werden.', - 'enderauge': 'Ein Enderauge kann gecraftet werden, indem im Craftingfeld Lohenstaub neben einer Enderperle platziert wird.', - 'kohleblock': 'Ein Kohleblock kann gecraftet werden, indem Kohle in einem 3x3-Raster in einem Craftingfeld platziert wird.', - 'netherstern': 'Ein Netherstern kann erhalten werden, indem der Wither besiegt wird.', - 'kies': 'Kies erhält man, indem Kiesblöcke zerkleinert werden.', - 'blaue wolle': 'Blaue Wolle kann gecraftet werden, indem im Craftingfeld Blauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'netherquarz': 'Netzerquarz kann erhalten werden, indem Netzquarzerz in einem Ofen geschmolzen wird.', - 'verrottetes fleisch': 'Verrottetes Fleisch kann zufällig durch das Töten von Zombies erhalten werden.', - 'magenta teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'weiß gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'birkenholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'karotten': 'Karotten können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'violetter farbstoff': 'Violetter Farbstoff kann gecraftet werden, indem im Craftingfeld Lapislazuli neben Rotem Farbstoff platziert wird.', - 'lapislazuliblock': 'Ein Lapislazuliblock kann erhalten werden, indem eine Werkbank vollständig mit Lapislazuli ausgefüllt wird.', - 'obsidian': 'Obsidian kann mit einer Diamantspitzhacke abgebaut oder hergestellt werden, indem Wasser über Lava platziert wird. ', - 'schallplatte mellohi': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'graue wolle': 'Graue Wolle kann gecraftet werden, indem im Craftingfeld Grauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'redstonetruhe': 'Eine Redstonetruhe kann gecraftet werden, indem in einem Craftingfeld ein Haken neben einer Truhe platziert wird.', - 'hellgrau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'eisenspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'roter pilz': 'Rote Pilze können natürlich in schlecht beleuchteten Bereichen, Pilzbiomen oder im Nether gefunden werden.', - 'kugelfisch': 'Ein Kugelfisch kann zufällig durch Angeln erhalten werden.', - 'smaragd': 'Smaragde können durch den Abbau von Smaragderz gewonnen.', - 'holzschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'goldhelm': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'melone': 'Eine Melone kommt natürlich in Dschungeln vor oder kann mithilfe aus in Güterloren in verlassenen Minen gefundenen Melonenkernen angebaut werden.', - 'tonblock': 'Ton wird gewöhnlich auf dem Boden von Flüssen und Seen in flachen, runden Stellen gefunden. Tonblöcke können gewöhnlich auch in Sümpfen gefunden werden.', - 'amboss': 'Ein Amboss kann gecraftet werden, indem in einer Werkbank drei Eisenblöcke in die oberste Reihe, ein Eisenbarren in das Feld ganz in der Mitte und dann drei Eisenbarren in der unteren Reihe platziert werden.', - 'tageslichtsensor': 'Ein Tageslichtsensor kann gecraftet werden, indem in einer Werkbank drei Mal Glas in der oberen Reihe, drei Netherquarze in der mittleren Reihe und drei Holzstufen in der unteren Reihe platziert werden.', - 'sandstein': 'Sandstein kann in Wüsten gewonnen oder durch die Kombination von Sand in einem 2x2-Raster gecraftet werden.', - 'lederjacke': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'schwarz gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'hellgrün gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'tnt-lore': 'Eine TNT-Lore wird gecraftet, indem ein TNT in einer Werkbank über einer Lore platziert wird.', - 'uhr': 'Eine Uhr wird hergestellt, indem ein Redstone in einer Werkbank im mittleren Feld platziert und von vier Goldbarren umgeben wird.', - 'schwarzer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'kakao': 'Kakao entsteht aus Kakaopflanzen, die im Dschungel natürlich vorkommen. Kakaobohnen werden in Minecraft als Brauner Farbstoff verwendet.', - 'goldbarren': 'Goldbarren können erhalten werden, indem Golderz in einem Ofen geschmolzen wird.', - 'steinziegelstufe': 'Eine Steinziegelstufe kann hergestellt werden, indem in einer Werkbank drei Steinziegel in einer Reihe platziert werden.', - 'clownfisch': 'Ein Clownfisch kann zufällig durch Angeln erhalten werden.', - 'kürbiskerne': 'Kürbiskerne können gecraftet werden, indem ein Kürbis in einem Craftingfeld platziert wird.', - 'bemooster steinziegel': 'Ein bemooster Steinziegel kann gecraftet werden, indem Ranken in einer Werkbank im Feld neben Steinziegeln platziert werden. Ein bemooster Steinziegel kann auch natürlich in Festungen vorkommen.', - 'spinnennetz': 'Spinnennetze erhält man durch die Verwendung einer Schere oder eines Schwerts, das mit Behutsamkeit verzaubert ist.', - 'milcheimer': 'Ein Milcheimer kann durch einen Rechtsklick auf eine Kuh mit einem Eiseneimer erhalten werden.', - 'eisenhelm': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'gelb gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'hellgrau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'diamant': 'Diamanten erhält man, indem Diamanterz mit einer Spitzhacke aus Eisen oder einem hochwertigerem Material abgebaut wird.', - 'steinschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'bruchsteintreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'bett': 'Ein Bett kann gecraftet werden, indem in einer Werkbank drei Mal Wolle in der oberen Reihe und drei Holzbretter in der mittleren Reihe platziert werden.', - 'birkenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'quarzstufe': 'Eine Quarzstufe kann hergestellt werden, indem in einer Werkbank drei Quarzblöcke in einer Reihe platziert werden.', - 'schwamm': 'Schwämme können durch Töten eines großen Wächters gewonnen oder zufällig in Ozeanmonumenten gefunden werden.', - 'skelettschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'eimer': 'Ein Eimer kann hergestellt werden, indem in einer Werkbank drei Eisenbarren V-förmig platziert werden.', - 'diamantschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'goldschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'fichtenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'eisengitter': 'Ein Eisengitter kann gecraftet werden, indem sechs Eisenbarren in die beiden unteren Reihen einer Werkbank platziert werden, Ein Eisengitter kann auch natürlich in Festungen vorkommen.', - 'rohes kaninchen': 'Rohes Kaninchen kann zufällig durch das Töten eines Kaninchens erhalten werden.', - 'gelber teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld platziert wird.', - 'karottenrute': 'Eine Karottenrute kann gecraftet werden, indem im Craftingfeld eine Angel im mittleren linken Feld und eine Karotte im unteren mittleren Feld platziert werden.', - 'rohes schweinefleisch': 'Rohes Schweinefleisch kann durch das Töten eines Schweins erhalten werden.', - 'ofen': 'Ein Ofen kann gecraftet werden, indem Bruchstein in alle Felder einer Werkbank mit Ausnahme des Feldes ganz in der Mitte platziert werden.', - 'netherziegelzaun': 'Ein Netzziegelzaun kann gecraftet werden, indem sechs Netherziegel in die beiden unteren Reihen einer Werkbank platziert werden.', - 'zaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'diamantene pferderüstung': 'Eine Pferderüstung kann zufällig in Verliesen, Netherfestungen, bei Schmieden, in Dschungeltempeln, Wüstentempeln und Truhen in Festungen gefunden werden.', - 'rote sandsteinstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'birkenholzbrett': 'Birkenholzbretter können erhalten werden, indem Birkenholz in einer Werkbank platziert wird.', - 'grundgestein': 'Grundgestein kann in Minecraft nur durch Cheats gewonnen werden, Es ist der unterste Block des Spiels.', - 'sattel': 'Sättel können nicht gecraftet werden, sondern nur in Truhen in Verliesen, verlassenen Minenschächten, Netherfestungen, Wüstentempeln oder Dschungeltempeln gefunden werden.', - 'hellgrauer farbstoff': 'Hellgrauer Farbstoff kann gecraftet werden, indem im Craftingfeld zwei Mal Knochenmehl in einer senkrechten Reihe neben einem Tintenbeutel platziert wird.', - 'tropenbaumlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'schallplatte blocks': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'kürbis': 'Kürbisse sind in den meisten Biomen selten auf Grasblöcken zu finden.', - 'ofenkartoffel': 'Eine Ofenkartoffel kann erhalten werden, indem eine Kartoffel in einem Ofen geschmolzen wird.', - 'leder': 'Leder kann zufällig durch das Töten von Kühen oder Pferden erhalten werden.', - 'hellgrauer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'eisenstiefel': 'Alle Stiefel lassen sich craften, indem das gewünschte Material im linken mittleren, linken unteren, rechten mittleren und rechten unteren Feld einer Werkbank platziert wird.', - 'endstein': 'Endstein kann naturgemäß in der Ende-Dimension gefunden werden.', - 'kettenhose': 'Eine Kettenrüstung kann durch den Handel mit einem Dorfbewohner oder einen seltenen Drop von einer Kreatur erhalten werden.', - 'hasenpfote': 'Eine Hasenpfote kann in seltenen Fällen beim Töten eines Hasens erhalten werden.', - 'glas': 'Glas wird erhalten, indem Sand in einem Ofen geschmolzen wird.', - 'stein': 'Stein wird hergestellt, indem Bruchstein in einem Ofen geschmolzen wird.', - 'prismarin': 'Prismarin kann gecraftet werden, indem Prismarinscherben in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'kompass': 'Ein Kompass wird hergestellt, indem ein Redstone in einer Werkbank im mittleren Feld platziert und von vier Eisenbarren umgeben wird.', - 'grün gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'goldhose': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'befehlsblock': 'Befehlsblöcke können in Minecraft nur durch Cheats erhalten werden.', - 'werfer': 'Ein Werfer kann hergestellt werden, indem ein Bogen im mittleren Feld, Redstone direkt darunter und Bruchstein in allen anderen Feldern platziert werden.', - 'giftige kartoffel': 'Eine Giftige Kartoffel droppt zufällig beim Ernten von Kartoffeln.', - 'apfel': 'Äpfel droppen zufällig von Eichen und Schwarzeichenlaub. Sie können auch zufällig in Truhen in Festungen und Dörfern gefunden werden.', - 'rote blume': 'Mohn kann naturgemäß auf Gras gefunden oder zufällig hergestellt werden, indem Knochenmehl auf Gras angewandt wird.', - 'magenta farbstoff': 'Magenta Farbstoff kann gecraftet werden, indem in einem Craftingfeld Violetter Farbstoff neben Rosa Farbstoff platziert wird.', - 'brauner teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'prismarinscherbe': 'Prismarinscherben können durch das Besiegen von Wächtern und großen Wächtern erhalten werden.', - 'redstone-block': 'Ein Redstone-Block kann gecraftet werden, indem neun Redstones in einem 3x3-Raster in einer Werkbank platziert werden.', - 'gelb gefärbte glasscheibe': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'löwenzahngelb': 'Löwenzahngelb entspricht dem Gelben Farbstoff in Minecraft. Es kann gecraftet werden, indem ein Löwenzahn oder eine Sonnenblume in einem Craftingfeld platziert wird.', - 'akazienholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'sandsteinstufe': 'Eine Sandsteinstufe kann hergestellt werden, indem in einer Werkbank drei Sandstein-Blöcke in einer Reihe platziert werden.', - 'grauer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'polierter granit': 'Polierter Granit kann gecraftet werden, indem vier Mal Granit in einem 2x2-Raster in einer Werkbank platziert wird.', - 'lore': 'Eine Lore kann gecraftet werden, indem fünf Eisenbarren U-förmig in einer Werkbank platziert werden.', - 'braun gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'türkis gefärbte glasscheibe': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'buch': 'Ein Buch wird mithilfe eines 2x2-Rasters in einem Craftingfeld hergestellt, bei dem in das rechte untere Feld Leder und in allen anderen Feldern Papier platziert wird.', - 'güterlore': 'Eine Güterlore wird gecraftet, indem eine Truhe in einem Craftingfeld über einer Lore platziert wird.', - 'akaziensetzling': 'Akaziensetzlinge können zufällig erhalten werden, indem Akazienlaub zerstört wird.', - 'papier': 'Brot kann gecraftet werden, indem in einer Werkbank drei Mal Zuckerrohr in einer Reihe platziert wird.', - 'türkis gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'pilzsuppe': 'Die Pilzsuppe oder der Pilzeintopf wird gecraftet, indem in einer Werkbank ein Roter Pilz im mittleren linken Feld, ein Brauner Pilz im mittleren Feld und eine Schüssel im unteren mittleren Feld platziert werden.', - 'netherziegel': 'Netherziegel kann mit einer Spitzhacke abgebaut oder gecraftet werden, indem in der Werkbank in einem 2x2-Raster vier Netherziegel platziert werden.', - 'magmacreme': 'Magmacreme kann gecraftet werden, indem in einem Craftingfeld Lohenstaub neben einem Schleimball platziert wird.', - 'schnee': 'Schnee kann gecraftet werden, indem Schneebälle in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'oranger farbstoff': 'Oranger Farbstoff kann gecraftet werden, indem im Craftingfeld Roter Farbstoff neben einem Gelben Farbstoff platziert wird.', - 'trank': 'Ein Trank wird mithilfe eines Braustands, eines Kessels und Wasserflaschen hergestellt.', - 'hellgrün gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'weiß gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'boot': 'Ein Boot kann erhalten werden, indem fünf Holzbretter U-förmig platziert werden.', - 'dunkler prismarin': 'Dunkle Prismarine können gecraftet werden, indem ein Tintenbeutel im mittleren Feld platziert und dann von acht Prismarinscherben umgeben wird.', - 'eichenholztür': 'Eine Eichenholztür kann gecraftet werden, indem sechs Eichenbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'eichenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'rote wolle': 'Rote Wolle kann gecraftet werden, indem im Craftingfeld Roter Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'gebratenes hammelfleisch': 'Gebratenes Hammelfleisch wird erhalten, indem Rohes Hammelfleisch in einem Ofen gebraten wird. Alternativ dazu droppen ein bis zwei Stücke Gebratenes Hammelfleisch, wenn ein brennendes Schaf stirbt.', - 'schwarzeichenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'eisentür': 'Eine Eisentür kann gecraftet werden, indem sechs Eisenbarren in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'gemälde': 'Ein Gemälde wird gecraftet, indem Wolle im mittleren Feld platziert und von acht Stöcken umgeben wird.', - 'fichtennadeln': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'rosa gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'akazienholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'schwarzeichenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'gemeißelter sandstein': 'Gemeißelter Sandstein kann hergestellt werden, indem im Craftingfeld eine Sandsteinstufe über einer anderen platziert wird.', - 'eichenholzbrett': 'Eichenholzbretter können erhalten werden, indem Eichenholz in einer Werkbank platziert wird.', - 'gebratener lachs': 'Gebratener Lachs wird erhalten, indem Lachs in einem Ofen gebraten wird.', - 'eisenschaufel': 'Jede Art von Schaufel lässt sich craften, indem auf der Werkbank das gewünschte Material in das obere mittlere Feld gelegt wird und dann Stöcke in die beiden direkt darunter befindlichen Felder platziert werden.', - 'zaubertisch': 'Ein Zaubertisch kann gecraftet werden, indem in der Werkbank ein Buch in das obere mittlere Feld, Diamanten in das mittlere linke und mittlere rechte Feld und Obsidian ganz in die Mitte und in alle Felder der untersten Reihe platziert werden.', - 'redstone-verstärker': 'Ein Redstone-Verstärker kann gecraftet werden, indem glatter Stein in allen drei Feldern der untersten Reihe, Redstone ganz in der Mitte und Redstone-Fackeln links und rechts vom Redstone platziert werden.', - 'schallplatte far': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'grüner teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'eisenbarren': 'Eisenbarren können erhalten werden, indem Eisenerz in einem Ofen geschmolzen wird.', - 'orange wolle': 'Orange Wolle kann gecraftet werden, indem im Craftingfeld Oranger Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'tropenbaumsetzling': 'Tropenbaumsetzlinge können zufällig erhalten werden, indem Tropenbaumlaub zerstört wird.', - 'steinstufe': 'Eine Steinstufe kann hergestellt werden, indem in einer Werkbank drei Stein-Blöcke in einer Reihe platziert werden.', - 'hellblau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'türkiser farbstoff': 'Türkiser Farbstoff kann gecraftet werden, indem im Craftingfeld Lapislazuli neben Kaktusgrün platziert wird.', - 'steak': 'Rohes Rindfleisch kann zu Steak zubereitet werden, indem es in einem Ofen geschmolzen wird. Alternativ dazu besteht die Chance, dass Steak droppt, wenn eine brennende Kuh oder Moo stirbt.', - 'orange gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'blau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'fichtenholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'kohle': 'Kohle erhält man, indem Steinkohleblöcke mit einer Spitzhacke aus Holz oder aus einem hochwertigerem Material abgebaut werden.', - 'kartoffeln': 'Kartoffeln können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'hellgrau gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'zauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'ei': 'Eier werden von Hühnern zufällig gelegt. Das Werfen eines Eis kann mitunter ein neues Küken spawnen.', - 'fichtenholzbrett': 'Fichtenholzbretter können erhalten werden, indem Fichtenholz in einer Werkbank platziert wird.', - 'orange gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'akazienholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'hellgraue wolle': 'Hellgrau Wolle kann gecraftet werden, indem im Craftingfeld Hellgrauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'strohballen': 'Ein Strohballen kann gecraftet werden, indem Weizen in einem 3x3-Raster in einer Werkbank platziert wird.', - 'ton': 'Ton wird erhalten, indem man Tonblöcke mit einer nicht mit Behutsamkeit verzauberten Spitzhacke abbaut.', - 'schüssel': 'Eine Schüssel kann hergestellt werden, indem in einer Werkbank drei Holzbretter V-förmig platziert werden.', - 'lederkappe': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'rosa gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'diamantbrustpanzer': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'grau gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - 'schneemann': 'Ein Schneegolem kann erschaffen werden, indem ein Kürbis auf zwei auf dem Boden stehende Schneeblöcke gesetzt wird.', - 'diamanterz': 'Diamanterz kann in den unteren sechzehn Schichten der Karte gefunden werden. Diamanterz kann mit einer Spitzhacke aus Eisen oder hochwertigerem Material zerbrochen werden. Damit wird das Diamanterz zu einem Diamanten. Um das Erz zu erhalten, muss eine Spitzhacke mit der Verzauberung Behutsamkeit verwendet werden.', - 'banner': 'Ein Banner kann gecraftet werden, indem sechs Mal Wolle in die beiden oberen Reihen und ein Stock im unteren mittleren Feld platziert werden. Das Banner nimmt die Farbe der ausgewählten Wolle an.', - 'steinaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'feuerwerksstern': 'Ein Feuerwerksstern kann gecraftet werden, indem in der Werkbank Schwarzpulver in das linke mittlere und Farbstoff einer beliebigen Farbe in das Feld ganz in der Mitte platziert werden. Außerdem kann ein Feuerwerksstern auch mit optionalen Materialien wie Diamanten, Glowstonestaub oder Federn gecraftet werden, die in der Werkbank direkt unterhalb des Farbstoffes platziert werden müssen.', - 'netherwarze': 'Netherwarzen treten natürlich in Pflanzenform in Netherfestungen auf.', - 'rot gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'quarzblock': 'Ein Quarzblock kann gecraftet werden, indem vier Mal Netherquarz in einem 2x2-Raster in einer Werkbank platziert wird.', - 'mohn': 'Mohn kann naturgemäß auf Gras gefunden oder zufällig hergestellt werden, indem Knochenmehl auf Gras angewandt wird.', - 'akazienholzzaun': 'Jede Art von Zaun kann gecraftet werden, indem ein Holzbrett, ein Stock und dann ein weiteres Holzbrett in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'kaktus': 'Kaktus kann naturgemäß in der Wüsten-Biomen gefunden werden. ', - 'fichtenholztür': 'Eine Fichtenholztür kann gecraftet werden, indem sechs Fichtenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'schallplatte cat': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'feuerzeug': 'Ein Feuerzeug kann gecraftet werden, indem im Craftingfeld ein Eisenbarren links von einem Feuerstein platziert wird.', - 'schleimball': 'Schleimbälle droppen zufällig beim Töten von Schleimen.', - 'gebratenes schweinefleisch': 'Gebratenes Schweinefleisch kann erhalten werden, indem Rohes Schweinefleisch in einem Ofen gebraten oder ein Schwein angezündet wird.', - 'polierter andesit': 'Polierter Andesit kann gecraftet werden, indem vier Mal Andesit in einem 2x2-Raster in einer Werkbank platziert wird.', - 'prismarinziegel': 'Prismarinziegel können gecraftet werden, indem Prismarinscherben in einem 3x3-Raster in einer Werkbank platziert werden.', - 'wither': 'Ein Wither kann erschaffen werden, indem man drei Witherskelettschädel auf Seelensand gibt, der wiederum T-förmig auf dem Boden platziert wird.', - 'hellgrüner farbstoff': 'Hellgrüner Farbstoff kann gecraftet werden, indem im Craftingfeld Kaktusgrün neben Knochenmehl platziert wird.', - 'blauer Teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'tür': 'Eine Tür kann gecraftet werden, indem sechs Bretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'stolperdraht': 'Stolperdraht ist einfach eine Schnur neben einem Haken.', - 'türkiser teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'polierter diorit': 'Polierter Diorit kann gecraftet werden, indem vier Mal Diorit in einem 2x2-Raster in einer Werkbank platziert wird.', - 'eisenblock': 'Ein Eisenblock kann gecraftet werden, indem Eisenbarren in einem 3x3-Raster in einer Werkbank platziert werden.', - 'akazienlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'schwarzeichensetzling': 'Schwarzeichensetzlinge können zufällig erhalten werden, indem Schwarzeichenlaub zerstört wird.', - 'diamantenhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'löwenzahn': 'Löwenzahn wächst natürlich auf Gras oder kann zufällig hergestellt werden, indem Knochenmehl auf Gras verwendet wird.', - 'lapislazuli': 'Kann erhalten werden, indem Lapislazulierz mit einer Spitzhacke aus Stein oder hochwertigerem Material abgebaut wird.', - 'zuckerrohr': 'Zuckerrohr kann naturgemäß in der Nähe von Wasser gefunden werden.', - 'birkenholztür': 'Eine Birkenholztür kann gecraftet werden, indem sechs Birkenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'kaktusgrün': 'Kaktusgrün kann gecraftet werden, indem ein Kaktus in einem Ofen geschmolzen wird.', - 'goldblock': 'Ein Goldblock kann gecraftet werden, indem Goldbarren in einem 3x3-Raster in einer Werkbank platziert werden.', - 'glatter sandstein': 'Glatter Sandstein kann gecraftet werden, indem in einem Craftingfeld vier Mal Sandstein in einem 2x2-Raster platziert wird.', - 'magenta gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'notenblock': 'Ein Notenblock wird gecraftet, indem ein Redstone in einer Werkbank im mittleren Feld platziert und von Holzbrettern umgeben wird.', - 'schnee-block': 'Schnee kann gecraftet werden, indem Schneebälle in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'kreaturenschädel': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'diamantbeinschutz': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'roter sandstein': 'Roter Sandstein kann gecraftet werden, indem vier Mal Roter Sand in einem 2x2-Craftingfeld platziert wird.', - 'orange gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'schleimblock': 'Ein Schleimblock kann gecraftet werden, indem Schleimbälle in einem 3x3-Raster in einem Craftingfeld platziert werden.', - 'bücherregal': 'Ein Bücherregal wird hergestellt, indem Bücher über die mittlere Reihe und Holzbretter in der oberen und unteren Reihe platziert werden.', - 'kuchen': 'Kuchen kann gecraftet werden, indem in der Werkbank drei Eimer Milch in der obersten Reihe, Zucker im linken mittleren und im rechten mittleren Feld, ein Ei im Feld ganz in der Mitte und drei Mal Weizen in der untersten Reihe platziert werden.', - 'holzknopf': 'Ein Holzknopf kann gecraftet werden, indem ein einziges Holzbrett in einem Craftingfeld platziert wird.', - 'gemeißelter quarzblock': 'Ein Gemeißelter Quarzblock kann erhalten werden, indem in einer Werkbank eine Quarzstufe über einer anderen platziert wird.', - 'steinknopf': 'Ein Steinknopf kann gecraftet werden, indem ein einziger glatter Stein in einem Craftingfeld platziert wird.', - 'glowstonestaub': 'Glowstonestaub wird durch den Abbau von Glowstoneblöcken erhalten.', - 'hellgrün gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'bruchsteinmauer': 'Eine Bruchsteinmauer wird gecraftet, indem sechs Bruchsteine in die beiden unteren Reihen einer Werkbank platziert werden.', - 'namensschild': 'Namensschilder können nur auf drei Arten erhalten werden. Sie können in einer Truhe in einem Verlies gefunden werden. Beim Angeln können Namensschilder auch erhalten werden. Der Tausch gegen zwanzig bis zweiundzwanzig Smaragde bei einem Bibliothekar-Dorfbewohner stellt die letzte Möglichkeit für den Erwerb eines Namensschildes dar.', - 'schwarzpulver': 'Schwarzpulver kann zufällig durch das Töten von Creepern erhalten werden.', - 'lohenstaub': 'Lohenstaub kann erhalten werden, indem eine Lohenrute in einer Werkbank platziert wird.', - 'braustand': 'Ein Braustand kann gecraftet werden, indem eine Lohenrute ganz in die Mitte und drei Bruchsteine in der untersten Reihe der Werkbank platziert werden.', - 'fackel': 'Ein Fackel kann gecraftet werden, indem ein Stück Kohle über einem Stock platziert wird.', - 'gelbe wolle': 'Gelbe Wolle kann gecraftet werden, indem im Craftingfeld Gelber Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'schallplatte wait': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'glitzernde melone': 'Eine Glitzernde Melone kann hergestellt werden, indem eine Melone in einer Werkbank im mittleren Feld platziert und von acht Goldklumpen umgeben wird.', - 'netherrack': 'Netherrack oder Netherstein kann gewöhnlich in der gesamten Nether-Dimension gefunden werden.', - 'holzstufe': 'Eine Holzstufe kann hergestellt werden, indem in einer Werkbank drei Holzbretter in einer Reihe platziert werden.', - 'netherziegeltreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'eis': 'Eis kommt natürlicherweise in Schnee-Biomen vor. Wenn es zerbrochen oder neben einer Hitzequelle platziert wird, schmilzt es zu Wasser. Um einen Eisblock zu erhalten, muss er mit einer Spitzhacke mit der Verzauberung Behutsamkeit abgebaut werden.', - 'großer farn': 'Großer Farn kommt natürlicherweise in Dschungel-, Taiga- und Riesentaiga-Biomen vor.', - 'netherziegelstufe': 'Eine Netherziegelstufe kann hergestellt werden, indem in einer Werkbank drei Netherziegel in einer Reihe platziert werden.', - 'fichtenholzstufe': 'Alle Arten von Stufen können gecraftet werden, indem eine Reihe der Werkbank mit dem gewünschten Material gefüllt wird.', - 'eisenhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'farn': 'Farn kommt natürlicherweise in Dschungel-, Taiga- und Riesentaiga-Biomen vor.', - 'seelaterne': 'Eine Seelaterne kann gecraftet werden, indem Prismarinscherben in die vier Ecken einer Werkbank platziert und in die anderen Felder Prismarinkristalle gegeben werden.', - 'keks': 'Ein Keks kann gecraftet werden, indem in der Werkbank in einer Reihe Weizen links und rechts von Kakaobohnen platziert wird.', - 'melonenkerne': 'Melonenkerne können gecraftet werden, indem eine Melonenscheibe in einem Craftingfeld platziert wird.', - 'goldklumpen': 'Goldklumpen können gecraftet werden, indem ein einziger Goldbarren in einem Craftingfeld platziert wird. Außerdem können sie zufällig durch das Töten eines Zombie-Pigmen erhalten werden.', - 'diamanthelm': 'Alle Helme werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des unteren mittleren Feldes und der obersten Reihe in einer Werkbank platziert wird.', - 'fichtenholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'goldhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'akazienholzbrett': 'Akazienholzbretter können erhalten werden, indem Akazienholz in einer Werkbank platziert wird.', - 'diamantspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'lapislazulierz': 'Lapislazulierz kann nur erhalten werden, indem eine Spitzhacke mit der Verzauberung Behutsamkeit verwendet wird.', - 'rohes hammelfleisch': 'Rohes Hammelfleisch kann durch das Töten eines Schafs erhalten werden.', - 'quarztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'ziegelstein-block': 'Ein Ziegelstein-Block kann gecraftet werden, indem Tonziegel in einem 2x2-Raster in einem Craftingfeld platziert werden.', - 'bruchsteinstufe': 'Eine Bruchsteinstufe kann hergestellt werden, indem in einer Werkbank drei Bruchstein-Blöcke in einer Reihe platziert werden.', - 'smaragderz': 'Smaragderz kann nur im Untergrund von Extremen Bergen zwischen den Schichten vier und zweiunddreißig gefunden werden. Es kann mit einer Eisenspitzhacke oder besser abgebaut werden, um Smaragde zu erhalten. Um das Erz selbst zu erhalten, wird eine Spitzhacke mit der Verzauberung Behutsamkeit benötigt.', - 'gelbe blume': 'Löwenzahn wächst natürlich auf Gras oder kann zufällig hergestellt werden, indem Knochenmehl auf Gras verwendet wird.', - 'kürbislaternen': 'Eine Kürbislaterne wird gecraftet, indem ein Kürbis in einer Werkbank über einer Fackel platziert wird.', - 'rot gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'eisenbeinschutz': 'Alle Hosen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des mittleren und des unteren mittleren Feldes in einer Werkbank platziert werden.', - 'rosa gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'schwarzer farbstoff': 'Ein Tintelbeutel wird in Minecraft als Schwarzer Farbstoff verwendet.', - 'holzhacke': 'Alle Arten von Hacken können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke und obere mittlere Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'violett gefärbtes glas': 'Alle Arten von gefärbtem Glas lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Glas umgeben wird.', - 'sensorschiene': 'Eine Sensorschiene kann gecraftet werden, indem eine Steindruckplatte im Feld ganz in der Mitte, Redstone im unteren mittleren Feld und Eisenbarren in den Feldern der rechten und linken Spalte platziert werden.', - 'türkise wolle': 'Türkise Wolle kann gecraftet werden, indem im Craftingfeld Türkiser Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'eisenbrustpanzer': 'Alle Brustrüstungen werden gecraftet, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren Feldes in einer Werkbank platziert wird.', - 'bruchstein': 'Bruchstein kann erhalten werden, indem Stein mit einer Spitzhacke abgebaut wird.', - 'schwarzeichenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'creeperkopf': 'Schädel erhält man, indem man mit einem geladenen Creeper die Kreatur explodieren lässt, deren Schädel man möchte.', - 'karotte': 'Karotten können selten durch das Töten von Zombies erhalten werden, oder sie können zum Anpflanzen in Dörfern gefunden werden.', - 'kaninchenfell': 'Kaninchenfell kann zufällig durch das Töten eines Kaninchens erhalten werden.', - 'gras': 'Wenn Gras mit einer gewöhnlichen Schaufel geerntet wird, verwandelt es sich in Erde. Um einen Grasblock zu erhalten, muss eine Schaufel mit der Verzauberung Behutsamkeit verwendet werden.', - 'schallplatte strad': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'birkensetzlinge': 'Birkensetzlinge können zufällig erhalten werden, indem Birkenlaub zerstört wird.', - 'moosstein': 'Bemooster Bruchstein oder früher Moosstein kann gecraftet werden, indem Ranken in einer Werkbank im Feld neben einem Bruchstein platziert werden. Er kann auch natürlicherweise in verschiedenen Verliesen gefunden werden.', - 'rosa farbstoff': 'Rosa Farbstoff kann gecraftet werden, indem im Craftingfeld Knochenmehl neben Rotem Farbstoff platziert wird.', - 'redstone-fackel': 'Eine Redstone-Fackel wird gecraftet, indem ein Redstone in einem Craftingfeld über einer Fackel platziert wird.', - 'grün gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'hohes gras': 'Hohes Gras, welches im Inventar Gras genannt wird, wächst auf Grasblöcken in bestimmten Biomen. Knochenmehl kann auf einem Grasblock verwendet werden, um Hohes Gras oder gelegentlich Blumen wachsen zu lassen.', - 'schwarze wolle': 'Schwarze Wolle kann gecraftet werden, indem im Craftingfeld ein Tintenbeutel neben Wolle einer beliebigen Farbe platziert wird.', - 'weizen': 'Weizen kann natürlicherweise in Dörfern gefunden oder aus Samen angebaut werden, die durch das Zerstören von Hohem Gras erhalten werden.', - 'enderperle': 'Enderperlen können zufällig durch das Töten von Endermen erhalten werden.', - 'angel': 'Eine Angel wird gecraftet, indem in einem Craftingfeld drei Stöcke in einer diagonalen Linie und dann zwei Mal Faden unter dem oberen rechten Stöck platziert werden.', - 'knochenmehl': 'Knochenmehl kann gecraftet werden, indem ein Knochen in einem Craftingfeld platziert wird.', - 'quarz': 'Netzerquarz kann erhalten werden, indem Netzquarzerz in einem Ofen geschmolzen wird.', - 'schwarzeichenholzbrett': 'Schwarzeichenholzbretter können erhalten werden, indem Schwarzeichenholz in einer Werkbank platziert wird.', - 'antriebsschiene': 'Eine Antriebsschiene kann gecraftet werden, indem ein Stock im Feld ganz in der Mitte, Redstone im unteren mittleren Feld und Goldbarren in den Feldern der rechten und linken Spalte platziert werden.', - 'leuchtfeuer': 'Ein Leuchtfeuer kann gecraftet werden, indem in einer Werkbank ein Netherstern ganz in der Mitte, drei Obsidiane in den Feldern der untersten Reihe und fünf Mal Glas in den verbleibenden Feldern platziert werden.', - 'blau gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'schwarzeichenholztür': 'Eine Schwarzeichenholztür kann gecraftet werden, indem sechs Schwarzeichenholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'eisengolem': 'Ein Eisengolem kann ähnlich wie ein Schneegolem erschaffen werden, indem ein Kürbiskopf auf zwei Eisenblöcken platziert wird. Danach muss links und rechts des Eisenblocks ganz in der Mitte jeweils ein Eisenblock platziert werden.', - 'fichtenholz': 'Alle Holzarten können erhalten werden, indem der entsprechende Baum zerstört wird.', - 'rosa wolle': 'Rosa Wolle kann gecraftet werden, indem im Craftingfeld Rosa Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'feuerkugel': 'Eine Feuerkugel kann gecraftet werden, indem in der Werkbank Lohenstaub im mittleren linken Feld, Kohle im Feld ganz in der Mitte und Schwarzpulver im unteren mittleren Feld platziert wird.', - 'akazienholztür': 'Eine Akazienholztür kann gecraftet werden, indem sechs Akazienholzbretter in den ersten beiden Spalten senkrecht nach unten platziert werden.', - 'schallplatte chirp': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'eichenlaub': 'Alles Laub kann erhalten werden, indem eine Schere mit dem gewünschten Laub benutzt wird.', - 'pfeil': 'Ein Pfeil kann gecraftet werden, indem in der Werkbank ein Feuerstein in das obere mittlere Feld, ein Stock in das Feld ganz in der Mitte und eine Feder in das untere mittlere Feld gelegt werden.', - 'holzaxt': 'Alle Arten von Äxten können gecraftet werden, indem das gewünschte Material in der Werkbank in das obere linke, obere mittlere und mittlere linke Feld und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert werden.', - 'glasscheibe': 'Eine Glasscheibe kann gecraftet werden, indem sechs Glasblöcke in die beiden unteren Reihen einer Werkbank platziert werden.', - 'endertruhe': 'Eine Endertruhe kann gecraftet werden, indem in einer Werkbank ein Enderauge im Feld ganz in der Mitte platziert und von acht Obsidian-Blöcken umgeben wird.', - 'hellblaue wolle': 'Hellblaue Wolle kann gecraftet werden, indem in einem Craftingfeld Hellblauer Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'faden': 'Faden kann zufällig durch das Töten von Spinnen oder das Zerstören von Spinnennetzen erhalten werden.', - 'rote sandsteintreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'violette wolle': 'Violette Wolle kann gecraftet werden, indem im Craftingfeld Violetter Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'schwarz gefärbter ton': 'Alle Arten gefärbten Tons lassen sich craften, indem der gewünschte Farbstoff im mittleren Feld platziert und von Gebranntem Ton umgeben wird.', - 'verzaubertes buch': 'Verzauberte Bücher können in den Truhen der Verliese, Festungen, Wüsten- und Dschungeltempel und Minen gefunden werden.', - 'knopf': 'Ein Knopf kann gecraftet werden, indem ein einziger glatter Stein oder ein einziges Holzbrett in einem Craftingfeld platziert wird.', - 'hellgrüne wolle': 'Hellgrüne Wolle kann gecraftet werden, indem im Craftingfeld Hellgrüner Farbstoff neben Wolle einer beliebigen Farbe platziert wird.', - 'grobe erde': 'Grobe Erde kann erhalten werden, indem Erde aus Riesentaiga-, Tafelberg- oder Savanne-Biomen zerbrochen wird.', - 'ghastträne': 'Ghasttränen können selten durch das Töten von Ghasts erhalten werden.', - 'seelensand': 'Seelensand kann gewöhnlich in der gesamten Nether-Dimension gefunden werden.', - 'brauner pilz': 'Braune Pilze können natürlich in schlecht beleuchteten Bereichen, Pilzbiomen oder im Nether gefunden werden.', - 'kettenhaube': 'Eine Kettenrüstung kann durch den Handel mit einem Dorfbewohner oder einen seltenen Drop von einer Kreatur erhalten werden.', - 'beschriebenes buch': 'Ein Beschriebenes Buch entsteht, wenn ein Buch und Feder signiert wird.', - 'fichtensetzling': 'Fichtensetzlinge können zufällig erhalten werden, indem Fichtennadeln zerstört werden.', - 'eichensetzling': 'Eichensetzlinge können zufällig erhalten werden, indem Eichenlaub zerstört wird.', - 'nachtlichtsensor': 'Durch einen Rechtsklick auf einen Tageslichtsensor kann dieser in einen Nachtlichtsensor umgewandelt werden.', - 'sandsteintreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'redstone-lampe': 'Eine Redstone-Lampe wird hergestellt, indem ein Glowstone in einer Werkbank im mittleren Feld platziert und von vier Redstones umgeben wird.', - 'glowstone': 'Glowstone kann auf den Decken in der Nether-Dimension gefunden werden.', - 'holzdruckplatte': 'Eine Holzdruckplatte lässt sich craften, indem zwei Holzbretter horizontal nebeneinander in das Craftingfeld gelegt werden.', - 'holzkohle': 'Holzkohle wird erhalten, indem Holzblöcke in einem Ofen geschmolzen werden.', - 'kettenstiefel': 'Eine Kettenrüstung kann durch den Handel mit einem Dorfbewohner oder einen seltenen Drop von einer Kreatur erhalten werden.', - 'leiter': 'Eine Leiter kann gecraftet werden, indem Stöcke in alle Felder einer Werkbank mit Ausnahme des Feldes ganz in der Mitte und des unteren mittleren Feldes platziert werden.', - 'bemooster bruchstein': 'Bemooster Bruchstein oder früher Moosstein kann gecraftet werden, indem Ranken in einer Werkbank im Feld neben einem Bruchstein platziert werden. Er kann auch natürlicherweise in verschiedenen Verliesen gefunden werden.', - 'goldspitzhacke': 'Alle Arten von Spitzhacken können gecraftet werden, indem das gewünschte Material drei Mal in der oberen Reihe der Werkbank und dann jeweils ein Stock in das Feld ganz in der Mitte und das in der Mitte der unteren Reihe platziert wird.', - 'akazienholzzauntor': 'Jede Art von Zauntor kann gecraftet werden, indem ein Stock, ein Holzbrett und dann ein weiterer Stock in einer Werkbank in den beiden unteren Reihen platziert werden.', - 'birkenholztreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'schallplatte ward': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'schallplatte': 'Eine zufällige Schallplatte kann droppen, wenn ein Creeper vom Pfeil eines Skeletts getötet wird. Alternativ dazu können Musikschallplatten auch in acht Prozent der Truhen in Verliesen gefunden werden.', - 'verzauberter goldener apfel': 'Ein verzauberter Goldener Apfel kann gecraftet werden, indem ein Apfel in das Feld ganz in der Mitte gelegt und dann von acht Goldblöcken umgeben wird.', - 'weißer teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'eisenschwert': 'Jede Art von Schwert lässt sich craften, indem auf einer Werkbank das gewünschte Material in das obere mittlere Feld sowie das Feld ganz in der Mitte platziert und dann ein Stock in das darunter befindliche Feld gelegt wird.', - 'gemeißelter roter sandstein': 'Gemeißelter roter Sandstein kann gecraftet werden, indem im Craftingfeld eine rote Sandsteinstufe über einer anderen roten Sandsteinstufe platziert wird.', - 'steinziegeltreppe': 'Jede Art von Treppe kann gecraftet werden, indem das gewünschte Material in allen Feldern der Werkbank mit Ausnahme des oberen mittleren, oberen rechten und mittleren rechten Feldes platziert wird.', - 'sruckplatte': 'Eine Druckplatte lässt sich craften, indem entweder zwei glatte Steine oder zwei Holzbretter horizontal nebeneinander in das Craftingfeld gelegt werden.', - 'tropenholzbrett': 'Tropenholzbretter können erhalten werden, indem Tropenholz in einer Werkbank platziert wird.', - 'grüne wolle': 'Grüne Wolle kann gecraftet werden, indem im Craftingfeld Kaktusgrün neben Wolle einer beliebigen Farbe platziert wird.', - 'bogen': 'Ein Bogen kann gecraftet werden, indem in einer Werkbank drei Mal Faden in den Feldern der rechten Spalte und dann drei Stöcke in Form eines Kleinerzeichens neben den Fäden platziert werden.', - 'hellgrüner teppich': 'Jede Art von Teppich lässt sich craften, indem zwei Mal Wolle der gleichen Farbe nebeneinander in das Craftingfeld gelegt wird.', - 'feuerstein': 'Flint droppt zufällig beim Zerbrechen von Kies.', - 'schwarz gefärbte glasscheibe': 'Alle verschiedenen gefärbten Glasscheiben lassen sich craften, indem Glas gleicher Farbe in den unteren beiden Reihen horizontal platziert wird.', - }, -}; diff --git a/examples/apps/alexa-smart-home-skill-adapter/template.yaml b/examples/apps/alexa-smart-home-skill-adapter/template.yaml deleted file mode 100644 index 09ee253e5c..0000000000 --- a/examples/apps/alexa-smart-home-skill-adapter/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Provides the basic framework for a skill adapter for a smart home skill. -Parameters: - TopicNameParameter: - Type: String -Resources: - alexasmarthomeskilladapter: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Provides the basic framework for a skill adapter for a smart home skill. - MemorySize: 128 - Timeout: 7 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter \ No newline at end of file diff --git a/examples/apps/algorithmia/index.js b/examples/apps/algorithmia/index.js deleted file mode 100644 index 9ce2af53a2..0000000000 --- a/examples/apps/algorithmia/index.js +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Algorithmia Lambda Function - * - * Calls any algorithm in the Algorithmia marketplace - * Get an API key and free credits by creating an account at algorithmia.com - * For more documentation see: algorithmia.com/docs/clients/lambda - * - * - * Follow these steps to encrypt your Algorithmia API Key for use in this function: - * - * 1. Create a KMS key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - * - * 2. Encrypt the event collector token using the AWS CLI - * aws kms encrypt --key-id alias/ --plaintext "" - * - * 3. Copy the base-64 encoded, encrypted key (CiphertextBlob) to the kmsEncryptedApiKey variable - * - * 4. Give your function's role permission for the kms:Decrypt action. - * Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} - */ -'use strict'; - -const algorithmia = require('algorithmia'); -const AWS = require('aws-sdk'); - -let apiKey; - -// Enter the base-64 encoded, encrypted key (CiphertextBlob) -const kmsEncryptedApiKey = ''; - -/* - * Configure your function to interact -*/ -const processEvent = (event, context) => { - /* - * Step 1: Set the algorithm you want to call - * This may be any algorithm in the Algorithmia marketplace - */ - const algorithm = 'algo://demo/Hello'; // algorithmia.com/algorithms/demo/Hello - - /* - * Step 2: Use your event source to set inputData according to the algorithm's input format - * This demo example uses the S3 Object's name as inputData - */ - const inputData = event.Records[0].s3.object.key; // Example for algo://demo/Hello - - /* Advanced example: - * Create 200x50 thumbnails for S3 file events using algo://opencv/SmartThumbnail - * Algorithm expects input as [URL, WIDTH, HEIGHT] - * Output is a base64 encoding of the resulting PNG thumbnail - * - * var algorithm = "algo://opencv/SmartThumbnail" - * var s3 = new AWS.S3(); - * var bucket = event.Records[0].s3.bucket.name; - * var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")) ; - * var params = {Bucket: bucket, Key: key}; - * var signedUrl = s3.getSignedUrl('getObject', params); - * var inputData = [signedUrl, 200, 50]; - */ - - // Run the algorithm - const client = algorithmia(apiKey); - client.algo(algorithm).pipe(inputData).then((output) => { - if (output.error) { - console.log(`Error: ${output.error.message}`); - context.fail(output.error.message); - } else { - /* - * Step 3: Process the algorithm output here - * This demo example prints and succeeds with the algorithm result - */ - console.log(output); - context.succeed(output.result); - } - }); -}; - -/* - * This is the lambda entrypoint (no modification necessary) - * it ensures apiKey is set (decrypting kmsEncryptedApiKey if provided) - * and then calls processEvent with the same event and context - */ -exports.handler = (event, context) => { - if (kmsEncryptedApiKey && kmsEncryptedApiKey !== '') { - const encryptedBuf = new Buffer(kmsEncryptedApiKey, 'base64'); - const cipherText = { CiphertextBlob: encryptedBuf }; - - const kms = new AWS.KMS(); - kms.decrypt(cipherText, (err, data) => { - if (err) { - console.log(`Decrypt error: ${err}`); - context.fail(err); - } else { - apiKey = data.Plaintext.toString('ascii'); - processEvent(event, context); - } - }); - } else if (apiKey) { - processEvent(event, context); - } else { - context.fail('API Key has not been set.'); - } -}; - diff --git a/examples/apps/algorithmia/package.json b/examples/apps/algorithmia/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/algorithmia/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/algorithmia/template.yaml b/examples/apps/algorithmia/template.yaml deleted file mode 100644 index e535de76cb..0000000000 --- a/examples/apps/algorithmia/template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Run any algorithm in the Algorithmia marketplace. -Parameters: - TopicNameParameter: - Type: String -Resources: - algorithmia: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Run any algorithm in the Algorithmia marketplace. - MemorySize: 256 - Timeout: 60 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: - Ref: Bucket1 - Events: - - 's3:ObjectCreated:*' - Bucket1: - Type: 'AWS::S3::Bucket' diff --git a/examples/apps/api-gateway-authorizer-nodejs/index.js b/examples/apps/api-gateway-authorizer-nodejs/index.js deleted file mode 100644 index a78b1faab3..0000000000 --- a/examples/apps/api-gateway-authorizer-nodejs/index.js +++ /dev/null @@ -1,379 +0,0 @@ -'use strict'; - -console.log('Loading function'); - - -/** - * AuthPolicy receives a set of allowed and denied methods and generates a valid - * AWS policy for the API Gateway authorizer. The constructor receives the calling - * user principal, the AWS account ID of the API owner, and an apiOptions object. - * The apiOptions can contain an API Gateway RestApi Id, a region for the RestApi, and a - * stage that calls should be allowed/denied for. For example - * { - * restApiId: 'xxxxxxxxxx, - * region: 'us-east-1, - * stage: 'dev', - * } - * - * const testPolicy = new AuthPolicy("[principal user identifier]", "[AWS account id]", apiOptions); - * testPolicy.allowMethod(AuthPolicy.HttpVerb.GET, "/users/username"); - * testPolicy.denyMethod(AuthPolicy.HttpVerb.POST, "/pets"); - * callback(null, testPolicy.build()); - * - * @class AuthPolicy - * @constructor - */ -function AuthPolicy(principal, awsAccountId, apiOptions) { - /** - * The AWS account id the policy will be generated for. This is used to create - * the method ARNs. - * - * @property awsAccountId - * @type {String} - */ - this.awsAccountId = awsAccountId; - - /** - * The principal used for the policy, this should be a unique identifier for - * the end user. - * - * @property principalId - * @type {String} - */ - this.principalId = principal; - - /** - * The policy version used for the evaluation. This should always be "2012-10-17" - * - * @property version - * @type {String} - * @default "2012-10-17" - */ - this.version = '2012-10-17'; - - /** - * The regular expression used to validate resource paths for the policy - * - * @property pathRegex - * @type {RegExp} - * @default '^\/[/.a-zA-Z0-9-\*]+$' - */ - this.pathRegex = new RegExp('^[/.a-zA-Z0-9-\*]+$'); - - // These are the internal lists of allowed and denied methods. These are lists - // of objects and each object has two properties: a resource ARN and a nullable - // conditions statement. The build method processes these lists and generates - // the appropriate statements for the final policy. - this.allowMethods = []; - this.denyMethods = []; - - if (!apiOptions || !apiOptions.restApiId) { - this.restApiId = '*'; - } else { - this.restApiId = apiOptions.restApiId; - } - if (!apiOptions || !apiOptions.region) { - this.region = '*'; - } else { - this.region = apiOptions.region; - } - if (!apiOptions || !apiOptions.stage) { - this.stage = '*'; - } else { - this.stage = apiOptions.stage; - } -} - -/** - * A set of existing HTTP verbs supported by API Gateway. This property is here - * only to avoid spelling mistakes in the policy. - * - * @property HttpVerb - * @type {Object} - */ -AuthPolicy.HttpVerb = { - GET: 'GET', - POST: 'POST', - PUT: 'PUT', - PATCH: 'PATCH', - HEAD: 'HEAD', - DELETE: 'DELETE', - OPTIONS: 'OPTIONS', - ALL: '*', -}; - -AuthPolicy.prototype = (function AuthPolicyClass() { - /** - * Adds a method to the internal lists of allowed or denied methods. Each object in - * the internal list contains a resource ARN and a condition statement. The condition - * statement can be null. - * - * @method addMethod - * @param {String} The effect for the policy. This can only be "Allow" or "Deny". - * @param {String} The HTTP verb for the method, this should ideally come from the - * AuthPolicy.HttpVerb object to avoid spelling mistakes - * @param {String} The resource path. For example "/pets" - * @param {Object} The conditions object in the format specified by the AWS docs. - * @return {void} - */ - function addMethod(effect, verb, resource, conditions) { - if (verb !== '*' && !Object.prototype.hasOwnProperty.call(AuthPolicy.HttpVerb, verb)) { - throw new Error(`Invalid HTTP verb ${verb}. Allowed verbs in AuthPolicy.HttpVerb`); - } - - if (!this.pathRegex.test(resource)) { - throw new Error(`Invalid resource path: ${resource}. Path should match ${this.pathRegex}`); - } - - let cleanedResource = resource; - if (resource.substring(0, 1) === '/') { - cleanedResource = resource.substring(1, resource.length); - } - const resourceArn = `arn:aws:execute-api:${this.region}:${this.awsAccountId}:${this.restApiId}/${this.stage}/${verb}/${cleanedResource}`; - - if (effect.toLowerCase() === 'allow') { - this.allowMethods.push({ - resourceArn, - conditions, - }); - } else if (effect.toLowerCase() === 'deny') { - this.denyMethods.push({ - resourceArn, - conditions, - }); - } - } - - /** - * Returns an empty statement object prepopulated with the correct action and the - * desired effect. - * - * @method getEmptyStatement - * @param {String} The effect of the statement, this can be "Allow" or "Deny" - * @return {Object} An empty statement object with the Action, Effect, and Resource - * properties prepopulated. - */ - function getEmptyStatement(effect) { - const statement = {}; - statement.Action = 'execute-api:Invoke'; - statement.Effect = effect.substring(0, 1).toUpperCase() + effect.substring(1, effect.length).toLowerCase(); - statement.Resource = []; - - return statement; - } - - /** - * This function loops over an array of objects containing a resourceArn and - * conditions statement and generates the array of statements for the policy. - * - * @method getStatementsForEffect - * @param {String} The desired effect. This can be "Allow" or "Deny" - * @param {Array} An array of method objects containing the ARN of the resource - * and the conditions for the policy - * @return {Array} an array of formatted statements for the policy. - */ - function getStatementsForEffect(effect, methods) { - const statements = []; - - if (methods.length > 0) { - const statement = getEmptyStatement(effect); - - for (let i = 0; i < methods.length; i++) { - const curMethod = methods[i]; - if (curMethod.conditions === null || curMethod.conditions.length === 0) { - statement.Resource.push(curMethod.resourceArn); - } else { - const conditionalStatement = getEmptyStatement(effect); - conditionalStatement.Resource.push(curMethod.resourceArn); - conditionalStatement.Condition = curMethod.conditions; - statements.push(conditionalStatement); - } - } - - if (statement.Resource !== null && statement.Resource.length > 0) { - statements.push(statement); - } - } - - return statements; - } - - return { - constructor: AuthPolicy, - - /** - * Adds an allow "*" statement to the policy. - * - * @method allowAllMethods - */ - allowAllMethods() { - addMethod.call(this, 'allow', '*', '*', null); - }, - - /** - * Adds a deny "*" statement to the policy. - * - * @method denyAllMethods - */ - denyAllMethods() { - addMethod.call(this, 'deny', '*', '*', null); - }, - - /** - * Adds an API Gateway method (Http verb + Resource path) to the list of allowed - * methods for the policy - * - * @method allowMethod - * @param {String} The HTTP verb for the method, this should ideally come from the - * AuthPolicy.HttpVerb object to avoid spelling mistakes - * @param {string} The resource path. For example "/pets" - * @return {void} - */ - allowMethod(verb, resource) { - addMethod.call(this, 'allow', verb, resource, null); - }, - - /** - * Adds an API Gateway method (Http verb + Resource path) to the list of denied - * methods for the policy - * - * @method denyMethod - * @param {String} The HTTP verb for the method, this should ideally come from the - * AuthPolicy.HttpVerb object to avoid spelling mistakes - * @param {string} The resource path. For example "/pets" - * @return {void} - */ - denyMethod(verb, resource) { - addMethod.call(this, 'deny', verb, resource, null); - }, - - /** - * Adds an API Gateway method (Http verb + Resource path) to the list of allowed - * methods and includes a condition for the policy statement. More on AWS policy - * conditions here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition - * - * @method allowMethodWithConditions - * @param {String} The HTTP verb for the method, this should ideally come from the - * AuthPolicy.HttpVerb object to avoid spelling mistakes - * @param {string} The resource path. For example "/pets" - * @param {Object} The conditions object in the format specified by the AWS docs - * @return {void} - */ - allowMethodWithConditions(verb, resource, conditions) { - addMethod.call(this, 'allow', verb, resource, conditions); - }, - - /** - * Adds an API Gateway method (Http verb + Resource path) to the list of denied - * methods and includes a condition for the policy statement. More on AWS policy - * conditions here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition - * - * @method denyMethodWithConditions - * @param {String} The HTTP verb for the method, this should ideally come from the - * AuthPolicy.HttpVerb object to avoid spelling mistakes - * @param {string} The resource path. For example "/pets" - * @param {Object} The conditions object in the format specified by the AWS docs - * @return {void} - */ - denyMethodWithConditions(verb, resource, conditions) { - addMethod.call(this, 'deny', verb, resource, conditions); - }, - - /** - * Generates the policy document based on the internal lists of allowed and denied - * conditions. This will generate a policy with two main statements for the effect: - * one statement for Allow and one statement for Deny. - * Methods that includes conditions will have their own statement in the policy. - * - * @method build - * @return {Object} The policy object that can be serialized to JSON. - */ - build() { - if ((!this.allowMethods || this.allowMethods.length === 0) && - (!this.denyMethods || this.denyMethods.length === 0)) { - throw new Error('No statements defined for the policy'); - } - - const policy = {}; - policy.principalId = this.principalId; - const doc = {}; - doc.Version = this.version; - doc.Statement = []; - - doc.Statement = doc.Statement.concat(getStatementsForEffect.call(this, 'Allow', this.allowMethods)); - doc.Statement = doc.Statement.concat(getStatementsForEffect.call(this, 'Deny', this.denyMethods)); - - policy.policyDocument = doc; - - return policy; - }, - }; -}()); - - -exports.handler = (event, context, callback) => { - // incoming token value - var token = event.authorizationToken; - console.log('Method ARN:', event.methodArn); - - // validate the incoming token - // and produce the principal user identifier associated with the token - - // this could be accomplished in a number of ways: - // 1. Call out to OAuth provider - // 2. Decode a JWT token inline - // 3. Lookup in a self-managed DB - const principalId = 'user|a1b2c3d4'; - - // you can send a 401 Unauthorized response to the client by failing like so: - // callback('Unauthorized'); - - // if the token is valid, a policy must be generated which will allow or deny access to the client - - // if access is denied, the client will recieve a 403 Access Denied response - // if access is allowed, API Gateway will proceed with the backend integration configured on the method that was called - - // build apiOptions for the AuthPolicy - const apiOptions = {}; - const tmp = event.methodArn.split(':'); - const apiGatewayArnTmp = tmp[5].split('/'); - const awsAccountId = tmp[4]; - apiOptions.region = tmp[3]; - apiOptions.restApiId = apiGatewayArnTmp[0]; - apiOptions.stage = apiGatewayArnTmp[1]; - /* - const method = apiGatewayArnTmp[2]; - let resource = '/'; // root resource - if (apiGatewayArnTmp[3]) { - resource += apiGatewayArnTmp[3]; - } - */ - - // this function must generate a policy that is associated with the recognized principal user identifier. - // depending on your use case, you might store policies in a DB, or generate them on the fly - - // keep in mind, the policy is cached for 5 minutes by default (TTL is configurable in the authorizer) - // and will apply to subsequent calls to any method/resource in the RestApi - // made with the same token - - // the example policy below denies access to all resources in the RestApi - const policy = new AuthPolicy(principalId, awsAccountId, apiOptions); - policy.denyAllMethods(); - // policy.allowMethod(AuthPolicy.HttpVerb.GET, "/users/username"); - - // finally, build the policy and exit the function - const authResponse = policy.build(); - - // new! -- add additional key-value pairs - // these are made available by APIGW like so: $context.authorizer. - // additional context is cached - authResponse.context = { - key: 'value', // $context.authorizer.key -> value - number: 1, - bool: true, - }; - // authResponse.context.arr = ['foo']; <- this is invalid, APIGW will not accept it - // authResponse.context.obj = {'foo':'bar'}; <- also invalid - - callback(null, authResponse); -}; diff --git a/examples/apps/api-gateway-authorizer-nodejs/package.json b/examples/apps/api-gateway-authorizer-nodejs/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/api-gateway-authorizer-nodejs/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/api-gateway-authorizer-nodejs/template.yaml b/examples/apps/api-gateway-authorizer-nodejs/template.yaml deleted file mode 100644 index e99aff6d64..0000000000 --- a/examples/apps/api-gateway-authorizer-nodejs/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Blueprint for API Gateway custom authorizers, implemented in NodeJS.' -Parameters: - TopicNameParameter: - Type: String -Resources: - apigatewayauthorizernodejs: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: 'Blueprint for API Gateway custom authorizers, implemented in NodeJS.' - MemorySize: 256 - Timeout: 5 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter \ No newline at end of file diff --git a/examples/apps/api-gateway-authorizer-python/lambda_function.py b/examples/apps/api-gateway-authorizer-python/lambda_function.py deleted file mode 100644 index cfd5e9f784..0000000000 --- a/examples/apps/api-gateway-authorizer-python/lambda_function.py +++ /dev/null @@ -1,223 +0,0 @@ -from __future__ import print_function - -import re - - -def lambda_handler(event, context): - # incoming token value - token = event['authorizationToken'] - print("Method ARN: " + event['methodArn']) - - ''' - Validate the incoming token and produce the principal user identifier - associated with the token. This can be accomplished in a number of ways: - - 1. Call out to the OAuth provider - 2. Decode a JWT token inline - 3. Lookup in a self-managed DB - ''' - principalId = 'user|a1b2c3d4' - - ''' - You can send a 401 Unauthorized response to the client by failing like so: - - raise Exception('Unauthorized') - - If the token is valid, a policy must be generated which will allow or deny - access to the client. If access is denied, the client will receive a 403 - Access Denied response. If access is allowed, API Gateway will proceed with - the backend integration configured on the method that was called. - - This function must generate a policy that is associated with the recognized - principal user identifier. Depending on your use case, you might store - policies in a DB, or generate them on the fly. - - Keep in mind, the policy is cached for 5 minutes by default (TTL is - configurable in the authorizer) and will apply to subsequent calls to any - method/resource in the RestApi made with the same token. - - The example policy below denies access to all resources in the RestApi. - ''' - tmp = event['methodArn'].split(':') - apiGatewayArnTmp = tmp[5].split('/') - awsAccountId = tmp[4] - - policy = AuthPolicy(principalId, awsAccountId) - policy.restApiId = apiGatewayArnTmp[0] - policy.region = tmp[3] - policy.stage = apiGatewayArnTmp[1] - policy.denyAllMethods() - #policy.allowMethod(HttpVerb.GET, '/pets/*') - - # Finally, build the policy - authResponse = policy.build() - - # new! -- add additional key-value pairs associated with the authenticated principal - # these are made available by APIGW like so: $context.authorizer. - # additional context is cached - context = { - 'key': 'value', # $context.authorizer.key -> value - 'number': 1, - 'bool': True - } - # context['arr'] = ['foo'] <- this is invalid, APIGW will not accept it - # context['obj'] = {'foo':'bar'} <- also invalid - - authResponse['context'] = context - - return authResponse - - -class HttpVerb: - GET = 'GET' - POST = 'POST' - PUT = 'PUT' - PATCH = 'PATCH' - HEAD = 'HEAD' - DELETE = 'DELETE' - OPTIONS = 'OPTIONS' - ALL = '*' - - -class AuthPolicy(object): - # The AWS account id the policy will be generated for. This is used to create the method ARNs. - awsAccountId = '' - # The principal used for the policy, this should be a unique identifier for the end user. - principalId = '' - # The policy version used for the evaluation. This should always be '2012-10-17' - version = '2012-10-17' - # The regular expression used to validate resource paths for the policy - pathRegex = '^[/.a-zA-Z0-9-\*]+$' - - '''Internal lists of allowed and denied methods. - - These are lists of objects and each object has 2 properties: A resource - ARN and a nullable conditions statement. The build method processes these - lists and generates the approriate statements for the final policy. - ''' - allowMethods = [] - denyMethods = [] - - # The API Gateway API id. By default this is set to '*' - restApiId = '*' - # The region where the API is deployed. By default this is set to '*' - region = '*' - # The name of the stage used in the policy. By default this is set to '*' - stage = '*' - - def __init__(self, principal, awsAccountId): - self.awsAccountId = awsAccountId - self.principalId = principal - self.allowMethods = [] - self.denyMethods = [] - - def _addMethod(self, effect, verb, resource, conditions): - '''Adds a method to the internal lists of allowed or denied methods. Each object in - the internal list contains a resource ARN and a condition statement. The condition - statement can be null.''' - if verb != '*' and not hasattr(HttpVerb, verb): - raise NameError('Invalid HTTP verb ' + verb + '. Allowed verbs in HttpVerb class') - resourcePattern = re.compile(self.pathRegex) - if not resourcePattern.match(resource): - raise NameError('Invalid resource path: ' + resource + '. Path should match ' + self.pathRegex) - - if resource[:1] == '/': - resource = resource[1:] - - resourceArn = 'arn:aws:execute-api:{}:{}:{}/{}/{}/{}'.format(self.region, self.awsAccountId, self.restApiId, self.stage, verb, resource) - - if effect.lower() == 'allow': - self.allowMethods.append({ - 'resourceArn': resourceArn, - 'conditions': conditions - }) - elif effect.lower() == 'deny': - self.denyMethods.append({ - 'resourceArn': resourceArn, - 'conditions': conditions - }) - - def _getEmptyStatement(self, effect): - '''Returns an empty statement object prepopulated with the correct action and the - desired effect.''' - statement = { - 'Action': 'execute-api:Invoke', - 'Effect': effect[:1].upper() + effect[1:].lower(), - 'Resource': [] - } - - return statement - - def _getStatementForEffect(self, effect, methods): - '''This function loops over an array of objects containing a resourceArn and - conditions statement and generates the array of statements for the policy.''' - statements = [] - - if len(methods) > 0: - statement = self._getEmptyStatement(effect) - - for curMethod in methods: - if curMethod['conditions'] is None or len(curMethod['conditions']) == 0: - statement['Resource'].append(curMethod['resourceArn']) - else: - conditionalStatement = self._getEmptyStatement(effect) - conditionalStatement['Resource'].append(curMethod['resourceArn']) - conditionalStatement['Condition'] = curMethod['conditions'] - statements.append(conditionalStatement) - - if statement['Resource']: - statements.append(statement) - - return statements - - def allowAllMethods(self): - '''Adds a '*' allow to the policy to authorize access to all methods of an API''' - self._addMethod('Allow', HttpVerb.ALL, '*', []) - - def denyAllMethods(self): - '''Adds a '*' allow to the policy to deny access to all methods of an API''' - self._addMethod('Deny', HttpVerb.ALL, '*', []) - - def allowMethod(self, verb, resource): - '''Adds an API Gateway method (Http verb + Resource path) to the list of allowed - methods for the policy''' - self._addMethod('Allow', verb, resource, []) - - def denyMethod(self, verb, resource): - '''Adds an API Gateway method (Http verb + Resource path) to the list of denied - methods for the policy''' - self._addMethod('Deny', verb, resource, []) - - def allowMethodWithConditions(self, verb, resource, conditions): - '''Adds an API Gateway method (Http verb + Resource path) to the list of allowed - methods and includes a condition for the policy statement. More on AWS policy - conditions here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition''' - self._addMethod('Allow', verb, resource, conditions) - - def denyMethodWithConditions(self, verb, resource, conditions): - '''Adds an API Gateway method (Http verb + Resource path) to the list of denied - methods and includes a condition for the policy statement. More on AWS policy - conditions here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition''' - self._addMethod('Deny', verb, resource, conditions) - - def build(self): - '''Generates the policy document based on the internal lists of allowed and denied - conditions. This will generate a policy with two main statements for the effect: - one statement for Allow and one statement for Deny. - Methods that includes conditions will have their own statement in the policy.''' - if ((self.allowMethods is None or len(self.allowMethods) == 0) and - (self.denyMethods is None or len(self.denyMethods) == 0)): - raise NameError('No statements defined for the policy') - - policy = { - 'principalId': self.principalId, - 'policyDocument': { - 'Version': self.version, - 'Statement': [] - } - } - - policy['policyDocument']['Statement'].extend(self._getStatementForEffect('Allow', self.allowMethods)) - policy['policyDocument']['Statement'].extend(self._getStatementForEffect('Deny', self.denyMethods)) - - return policy diff --git a/examples/apps/api-gateway-authorizer-python/template.yaml b/examples/apps/api-gateway-authorizer-python/template.yaml deleted file mode 100644 index 9287ef309d..0000000000 --- a/examples/apps/api-gateway-authorizer-python/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Blueprint for API Gateway custom authorizers, implemented in Python 2.7.' -Parameters: - TopicNameParameter: - Type: String -Resources: - apigatewayauthorizerpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: 'Blueprint for API Gateway custom authorizers, implemented in Python 2.7.' - MemorySize: 256 - Timeout: 5 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter diff --git a/examples/apps/api-gateway-multiple-origin-cors/README.md b/examples/apps/api-gateway-multiple-origin-cors/README.md deleted file mode 100644 index f4fd430df8..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# cors-multiple-origin - -*Example of Multiple-Origin CORS using API Gateway and Lambda* - -[Cross-Origin Resource Sharing (CORS) - MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) - -### Local development - -First, [set up the SAM CLI](https://github.com/awslabs/aws-sam-cli#installation). - -Now, test the application locally using: - -`sam local start-api` - -Note that there was an [issue](https://github.com/awslabs/aws-sam-cli/issues/400) that prevented OPTIONS requests from being handled when running with the SAM CLI version 0.3.0. This does not occur when the application is deployed. - -Run the tests: - -`npm install` - -`npm test` - -### Deploying - -```bash -sam package \ - --template-file template.yaml \ - --output-template-file packaged.yaml \ - --s3-bucket $YOUR_BUCKET_NAME -``` - -```bash -sam deploy \ - --template-file packaged.yaml \ - --stack-name cors-multiple-origin \ - --capabilities CAPABILITY_IAM -``` - -### Getting the URL of the deployed instance - -```bash -aws cloudformation describe-stacks \ - --stack-name cors-multiple-origin \ - --query 'Stacks[].Outputs' -``` \ No newline at end of file diff --git a/examples/apps/api-gateway-multiple-origin-cors/cors-config.json b/examples/apps/api-gateway-multiple-origin-cors/cors-config.json deleted file mode 100644 index 315af85e36..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/cors-config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "allowedOrigins": [ - "http://127.0.0.1", - "https://*.example.com", - "https://*.amazon.com" - ] -} \ No newline at end of file diff --git a/examples/apps/api-gateway-multiple-origin-cors/cors-util.js b/examples/apps/api-gateway-multiple-origin-cors/cors-util.js deleted file mode 100644 index 19a40f57b1..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/cors-util.js +++ /dev/null @@ -1,81 +0,0 @@ -// this is the list of headers allowed by default by the API Gateway console -// see: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html -// and: https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonRequestHeaders.html -const DEFAULT_ALLOWED_HEADERS = [ - "Content-Type", // indicates the media type of the resource - "X-Amz-Date", // the current date and time according to the requester (must be present for authorization) - "Authorization", // information required for request authentication - "X-Api-Key", // an AWS API key - "X-Amz-Security-Token" // see link above -]; -exports.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS; - -/** - * Extract the Origin header from a Lambda event - * @param event Lambda event - */ -exports.getOriginFromEvent = event => event.headers.Origin || event.headers.origin; - -/** - * Return an object that contains an Access-Control-Allow-Origin header - * if the request origin matches a pattern for an allowed origin. - * Otherwise, return an empty object. - * @param {String} origin the origin to test against the allowed list - * @param {Array} allowedOrigins A list of strings or regexes representing allowed origin URLs - * @return {Object} an object containing allowed header and its value - */ -exports.createOriginHeader = (origin, allowedOrigins) => { - if (!origin) - return {}; // no CORS headers necessary; browser will load resource - - // look for origin in list of allowed origins - const allowedPatterns = allowedOrigins.map(exports.compileURLWildcards); - const isAllowed = allowedPatterns.some(pattern => origin.match(pattern)); - if (isAllowed) - return {"Access-Control-Allow-Origin": origin}; - - // the origin does not match any allowed origins - return {}; // return no CORS headers; browser will not load resource - // we do not return a "null" origin because this is exploitable -}; - -/** - * Return an object that contains a preflight response to be returned - * from a Lambda function. - * @param {String} origin the origin to test against the allowed list - * @param {Array} allowedOrigins A list of strings or regexes representing allowed origin URLs - * @param {Array} allowedMethods a list of strings representing allowed HTTP methods - * @param {Array} allowedHeaders (optional) a list of strings representing allowed headers - * @param {Number} maxAge (optional) time in seconds until preflight response expires - * @return {Object} an object containing several header => value mappings - */ -exports.createPreflightResponse = (origin, allowedOrigins, allowedMethods, allowedHeaders = DEFAULT_ALLOWED_HEADERS, maxAge) => { - let headers = Object.assign(exports.createOriginHeader(origin, allowedOrigins), { - "Access-Control-Allow-Headers": allowedHeaders.join(","), - "Access-Control-Allow-Methods": allowedMethods.join(",") - }); - if (maxAge !== undefined) - headers["Access-Control-Max-Age"] = maxAge; - return {headers, statusCode: 204}; -}; - -/** - * Compiles a URL containing wildcards into a regular expression. - * - * Builds a regular expression that matches exactly the input URL, but allows - * any number of URL characters in place of each wildcard (*) character. - * http://*.example.com matches http://abc.xyz.example.com but not http://example.com - * http://*.example.com does not match http://example.org/.example.com - * @param {String} url the url to compile - * @return {RegExp} compiled regular expression - */ -exports.compileURLWildcards = (url) => { - // unreserved characters as per https://tools.ietf.org/html/rfc3986#section-2.3 - const urlUnreservedPattern = "[A-Za-z0-9\-._~]"; - const wildcardPattern = urlUnreservedPattern + "*"; - - const parts = url.split("*"); - const escapeRegex = str => str.replace(/([.?*+^$(){}|[\-\]\\])/g, "\\$1"); - const escaped = parts.map(escapeRegex); - return new RegExp("^" + escaped.join(wildcardPattern) + "$"); -}; \ No newline at end of file diff --git a/examples/apps/api-gateway-multiple-origin-cors/cors-util.test.js b/examples/apps/api-gateway-multiple-origin-cors/cors-util.test.js deleted file mode 100644 index 42423d9a80..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/cors-util.test.js +++ /dev/null @@ -1,84 +0,0 @@ -const cors = require("./cors-util"); - -// createOriginHeader -test("use createOriginHeader to make a header for no origin", () => { - const result = cors.createOriginHeader(undefined, []); - expect(result).toEqual({}); -}); - -test("use createOriginHeader to make a header for a single origin", () => { - const origin = "https://amazon.com"; - const allowedOrigins = [origin]; - const result = cors.createOriginHeader(origin, allowedOrigins); - expect(result).toEqual({"Access-Control-Allow-Origin": origin}); -}); - -test("use createOriginHeader to make a header for one of several origins", () => { - const origin = "https://amazon.com"; - const allowedOrigins = ["https://example.com", origin, "http://amazon.com"]; - const result = cors.createOriginHeader(origin, allowedOrigins); - expect(result).toEqual({"Access-Control-Allow-Origin": origin}); -}); - -test("use createOriginHeader to make a header for a disallowed origin", () => { - const origin = "https://not-amazon.com"; - const allowedOrigins = []; - const result = cors.createOriginHeader(origin, allowedOrigins); - expect(result).toEqual({}); -}); - -test("use createOriginHeader to make a header for a disallowed origin", () => { - const origin = "https://not-amazon.com"; - const allowedOrigins = ["https://example.com", "https://amazon.com", "http://amazon.com"]; - const result = cors.createOriginHeader(origin, allowedOrigins); - expect(result).toEqual({}); -}); - -// createPreflightResponse -test("use createPreflightResponse to make CORS preflight headers", () => { - const origin = "https://amazon.com"; - const allowedOrigins = [origin]; - const allowedMethods = ["CREATE", "OPTIONS"]; - const allowedHeaders = ["Authorization"]; - const maxAge = 8400; - const result = cors.createPreflightResponse(origin, allowedOrigins, allowedMethods, allowedHeaders, maxAge); - expect(result).toEqual({ - headers: { - "Access-Control-Allow-Origin": origin, - "Access-Control-Allow-Methods": "CREATE,OPTIONS", - "Access-Control-Allow-Headers": "Authorization", - "Access-Control-Max-Age": 8400 - }, - statusCode: 204 - }); -}); - -// compileURLWildcards -test("compile pattern with no wildcards", () => { - const pattern = "https://amazon.com"; - const regex = cors.compileURLWildcards(pattern); - expect(pattern).toMatch(regex); - expect("https://example.com").not.toMatch(regex); -}); - -test("test pattern with wildcard", () => { - const pattern = "https://*"; - const regex = cors.compileURLWildcards(pattern); - expect("https://example.com").toMatch(regex); -}); - -test("test pattern with subdomain wildcard", () => { - const pattern = "https://*.amazon.com"; - const regex = cors.compileURLWildcards(pattern); - expect("https://restaurants.amazon.com").toMatch(regex); - expect("https://amazon.com").not.toMatch(regex); - expect("https://x.y.z.amazon.com").toMatch(regex); - expect("https://restaurants.example.com").not.toMatch(regex); -}); - -test("test pattern with subdomain wildcard against malicious input", () => { - const pattern = "https://*.amazon.com"; - const regex = cors.compileURLWildcards(pattern); - expect("https://restaurants.amazon.com").toMatch(regex); - expect("https://my.website/restaurants.amazon.com").not.toMatch(regex); -}); \ No newline at end of file diff --git a/examples/apps/api-gateway-multiple-origin-cors/package-lock.json b/examples/apps/api-gateway-multiple-origin-cors/package-lock.json deleted file mode 100644 index 8489bfaa78..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/package-lock.json +++ /dev/null @@ -1,5075 +0,0 @@ -{ - "name": "cors-multiple-origin", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.0.0-beta.49", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz", - "integrity": "sha1-vs2AVIJzREDJ0TfkbXc0DmTX9Rs=", - "dev": true, - "requires": { - "@babel/highlight": "7.0.0-beta.49" - } - }, - "@babel/highlight": { - "version": "7.0.0-beta.49", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.49.tgz", - "integrity": "sha1-lr3GtD4TSCASumaRsQGEktOWIsw=", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^3.0.0" - } - }, - "abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", - "dev": true - }, - "acorn": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.6.2.tgz", - "integrity": "sha512-zUzo1E5dI2Ey8+82egfnttyMlMZ2y0D8xOCO3PNPPlYXpl8NZvF6Qk9L9BEtJs+43FqEmfBViDqc5d1ckRDguw==", - "dev": true - }, - "acorn-globals": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", - "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", - "dev": true, - "requires": { - "acorn": "^5.0.0" - } - }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-jest": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.0.1.tgz", - "integrity": "sha1-u6079SP7IC2gXtCmVAtIyE7tE6Y=", - "dev": true, - "requires": { - "babel-plugin-istanbul": "^4.1.6", - "babel-preset-jest": "^23.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-istanbul": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", - "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.13.0", - "find-up": "^2.1.0", - "istanbul-lib-instrument": "^1.10.1", - "test-exclude": "^4.2.1" - } - }, - "babel-plugin-jest-hoist": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.0.1.tgz", - "integrity": "sha1-6qEclkVjrqnCG+zvK994U/fzwUg=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-preset-jest": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.0.1.tgz", - "integrity": "sha1-YxzFRcbPAhlDATvK8i9F2H/mIZg=", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^23.0.1", - "babel-plugin-syntax-object-rest-spread": "^6.13.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "browser-process-hrtime": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", - "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", - "dev": true - }, - "browser-resolve": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", - "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", - "dev": true, - "requires": { - "resolve": "1.1.7" - } - }, - "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - }, - "capture-exit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", - "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", - "dev": true, - "requires": { - "rsvp": "^3.3.3" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "ci-info": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", - "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true, - "optional": true - }, - "compare-versions": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.3.0.tgz", - "integrity": "sha512-MAAAIOdi2s4Gl6rZ76PNcUa9IOYB+5ICdT41o5uMRf09aEu/F9RK+qhe8RjXNPwcTjGV7KU7h2P/fljThFVqyQ==", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "cssom": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", - "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", - "dev": true - }, - "cssstyle": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.3.1.tgz", - "integrity": "sha512-tNvaxM5blOnxanyxI6panOsnfiyLRj3HV4qjqqS45WPNS1usdYWRUQjqTEEELK73lpeP/1KoIGYUwrBn/VcECA==", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz", - "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==", - "dev": true, - "requires": { - "abab": "^1.0.4", - "whatwg-mimetype": "^2.0.0", - "whatwg-url": "^6.4.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", - "dev": true, - "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "dev": true, - "requires": { - "webidl-conversions": "^4.0.2" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0" - } - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, - "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.10.0.tgz", - "integrity": "sha512-fjUOf8johsv23WuIKdNQU4P9t9jhQ4Qzx6pC2uW890OloK3Zs1ZAoCNpg/2larNF501jLl3UNy0kIRcF6VI22g==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "exec-sh": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", - "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", - "dev": true, - "requires": { - "merge": "^1.1.3" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "^2.1.0" - }, - "dependencies": { - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" - } - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "expect": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-23.1.0.tgz", - "integrity": "sha1-v9/VeiogFw2HWZnul4fMcfAcIF8=", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "jest-diff": "^23.0.1", - "jest-get-type": "^22.1.0", - "jest-matcher-utils": "^23.0.1", - "jest-message-util": "^23.1.0", - "jest-regex-util": "^23.0.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fb-watchman": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", - "dev": true, - "requires": { - "bser": "^2.0.0" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "dev": true, - "requires": { - "glob": "^7.0.3", - "minimatch": "^3.0.3" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "^2.1.0" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", - "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", - "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" - } - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "import-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", - "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", - "dev": true, - "requires": { - "pkg-dir": "^2.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true - }, - "is-ci": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", - "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", - "dev": true, - "requires": { - "ci-info": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "^2.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-generator-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", - "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-odd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", - "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-api": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", - "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", - "dev": true, - "requires": { - "async": "^2.1.4", - "compare-versions": "^3.1.0", - "fileset": "^2.0.2", - "istanbul-lib-coverage": "^1.2.0", - "istanbul-lib-hook": "^1.2.0", - "istanbul-lib-instrument": "^1.10.1", - "istanbul-lib-report": "^1.1.4", - "istanbul-lib-source-maps": "^1.2.4", - "istanbul-reports": "^1.3.0", - "js-yaml": "^3.7.0", - "mkdirp": "^0.5.1", - "once": "^1.4.0" - } - }, - "istanbul-lib-coverage": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", - "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz", - "integrity": "sha512-eLAMkPG9FU0v5L02lIkcj/2/Zlz9OuluaXikdr5iStk8FDbSwAixTK9TkYxbF0eNnzAJTwM2fkV2A1tpsIp4Jg==", - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", - "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", - "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.0", - "semver": "^5.3.0" - } - }, - "istanbul-lib-report": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", - "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^1.2.0", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" - }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz", - "integrity": "sha512-8O2T/3VhrQHn0XcJbP1/GN7kXMiRAlPi+fj3uEHrjBD8Oz7Py0prSC25C09NuAZS6bgW1NNKAvCSHZXB0irSGA==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.2.0", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "istanbul-reports": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", - "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", - "dev": true, - "requires": { - "handlebars": "^4.0.3" - } - }, - "jest": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-23.1.0.tgz", - "integrity": "sha1-u7f4kxAKEadC3YvQ0EelSwlorRo=", - "dev": true, - "requires": { - "import-local": "^1.0.0", - "jest-cli": "^23.1.0" - }, - "dependencies": { - "jest-cli": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-23.1.0.tgz", - "integrity": "sha1-64vdTODRUlCJLjGtm2m8mdKo9r8=", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "import-local": "^1.0.0", - "is-ci": "^1.0.10", - "istanbul-api": "^1.3.1", - "istanbul-lib-coverage": "^1.2.0", - "istanbul-lib-instrument": "^1.10.1", - "istanbul-lib-source-maps": "^1.2.4", - "jest-changed-files": "^23.0.1", - "jest-config": "^23.1.0", - "jest-environment-jsdom": "^23.1.0", - "jest-get-type": "^22.1.0", - "jest-haste-map": "^23.1.0", - "jest-message-util": "^23.1.0", - "jest-regex-util": "^23.0.0", - "jest-resolve-dependencies": "^23.0.1", - "jest-runner": "^23.1.0", - "jest-runtime": "^23.1.0", - "jest-snapshot": "^23.0.1", - "jest-util": "^23.1.0", - "jest-validate": "^23.0.1", - "jest-watcher": "^23.1.0", - "jest-worker": "^23.0.1", - "micromatch": "^2.3.11", - "node-notifier": "^5.2.1", - "realpath-native": "^1.0.0", - "rimraf": "^2.5.4", - "slash": "^1.0.0", - "string-length": "^2.0.0", - "strip-ansi": "^4.0.0", - "which": "^1.2.12", - "yargs": "^11.0.0" - } - } - } - }, - "jest-changed-files": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-23.0.1.tgz", - "integrity": "sha1-95Vy0HIIROpd+EwqRI6GLCJU9gw=", - "dev": true, - "requires": { - "throat": "^4.0.0" - } - }, - "jest-config": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-23.1.0.tgz", - "integrity": "sha1-cIyg9DHTVu5CT7SJXTMIAGvdgkE=", - "dev": true, - "requires": { - "babel-core": "^6.0.0", - "babel-jest": "^23.0.1", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^23.1.0", - "jest-environment-node": "^23.1.0", - "jest-get-type": "^22.1.0", - "jest-jasmine2": "^23.1.0", - "jest-regex-util": "^23.0.0", - "jest-resolve": "^23.1.0", - "jest-util": "^23.1.0", - "jest-validate": "^23.0.1", - "pretty-format": "^23.0.1" - } - }, - "jest-diff": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-23.0.1.tgz", - "integrity": "sha1-PUkTfO4SwyCktNK0pvpugtSRoWo=", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff": "^3.2.0", - "jest-get-type": "^22.1.0", - "pretty-format": "^23.0.1" - } - }, - "jest-docblock": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-23.0.1.tgz", - "integrity": "sha1-3t3RgzO+XcJBUmCgTvP86SdrVyU=", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-23.1.0.tgz", - "integrity": "sha1-FhRrWSw1SGelrl4TzfFcbGW2lsY=", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "pretty-format": "^23.0.1" - } - }, - "jest-environment-jsdom": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-23.1.0.tgz", - "integrity": "sha1-hZKZFOI77TV32sl1X0EG0Gl8R5w=", - "dev": true, - "requires": { - "jest-mock": "^23.1.0", - "jest-util": "^23.1.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-23.1.0.tgz", - "integrity": "sha1-RSwL+UnPy7rNoeF2Lu7XC8eEx9U=", - "dev": true, - "requires": { - "jest-mock": "^23.1.0", - "jest-util": "^23.1.0" - } - }, - "jest-get-type": { - "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", - "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", - "dev": true - }, - "jest-haste-map": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-23.1.0.tgz", - "integrity": "sha1-GObH1ajScTb5G32YUvhd4McHTEk=", - "dev": true, - "requires": { - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.1.11", - "jest-docblock": "^23.0.1", - "jest-serializer": "^23.0.1", - "jest-worker": "^23.0.1", - "micromatch": "^2.3.11", - "sane": "^2.0.0" - } - }, - "jest-jasmine2": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-23.1.0.tgz", - "integrity": "sha1-SvqzFym2VN3NKwdK3YSTlvE7MLg=", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "co": "^4.6.0", - "expect": "^23.1.0", - "is-generator-fn": "^1.0.0", - "jest-diff": "^23.0.1", - "jest-each": "^23.1.0", - "jest-matcher-utils": "^23.0.1", - "jest-message-util": "^23.1.0", - "jest-snapshot": "^23.0.1", - "jest-util": "^23.1.0", - "pretty-format": "^23.0.1" - } - }, - "jest-leak-detector": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-23.0.1.tgz", - "integrity": "sha1-nboHUFrDSVw50+wJrB5WRZnoYaA=", - "dev": true, - "requires": { - "pretty-format": "^23.0.1" - } - }, - "jest-matcher-utils": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-23.0.1.tgz", - "integrity": "sha1-DGwNrt+YM8Kn82I2Bp7+y0w/bl8=", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", - "pretty-format": "^23.0.1" - } - }, - "jest-message-util": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.1.0.tgz", - "integrity": "sha1-moCbpIfsrFzlEdTmmO47XuJGHqk=", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0-beta.35", - "chalk": "^2.0.1", - "micromatch": "^2.3.11", - "slash": "^1.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-23.1.0.tgz", - "integrity": "sha1-o4HDGxIasfYMRiotrbe4bczKxIc=", - "dev": true - }, - "jest-regex-util": { - "version": "23.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-23.0.0.tgz", - "integrity": "sha1-3Vwf3gxG9DcTFM8Q96dRoj9Oj3Y=", - "dev": true - }, - "jest-resolve": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-23.1.0.tgz", - "integrity": "sha1-ueMW7s69bwC8UKOWDRUnuuZXktI=", - "dev": true, - "requires": { - "browser-resolve": "^1.11.2", - "chalk": "^2.0.1", - "realpath-native": "^1.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-23.0.1.tgz", - "integrity": "sha1-0BoQ3a2RUsTOzfXqwriFccS2pk0=", - "dev": true, - "requires": { - "jest-regex-util": "^23.0.0", - "jest-snapshot": "^23.0.1" - } - }, - "jest-runner": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-23.1.0.tgz", - "integrity": "sha1-+iCpM//3MaVDKzVh5/ZCZZT6KbU=", - "dev": true, - "requires": { - "exit": "^0.1.2", - "graceful-fs": "^4.1.11", - "jest-config": "^23.1.0", - "jest-docblock": "^23.0.1", - "jest-haste-map": "^23.1.0", - "jest-jasmine2": "^23.1.0", - "jest-leak-detector": "^23.0.1", - "jest-message-util": "^23.1.0", - "jest-runtime": "^23.1.0", - "jest-util": "^23.1.0", - "jest-worker": "^23.0.1", - "source-map-support": "^0.5.6", - "throat": "^4.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "jest-runtime": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-23.1.0.tgz", - "integrity": "sha1-tK4OhyWeys/UqIS2OdsHz03WIK8=", - "dev": true, - "requires": { - "babel-core": "^6.0.0", - "babel-plugin-istanbul": "^4.1.6", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "exit": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.11", - "jest-config": "^23.1.0", - "jest-haste-map": "^23.1.0", - "jest-message-util": "^23.1.0", - "jest-regex-util": "^23.0.0", - "jest-resolve": "^23.1.0", - "jest-snapshot": "^23.0.1", - "jest-util": "^23.1.0", - "jest-validate": "^23.0.1", - "micromatch": "^2.3.11", - "realpath-native": "^1.0.0", - "slash": "^1.0.0", - "strip-bom": "3.0.0", - "write-file-atomic": "^2.1.0", - "yargs": "^11.0.0" - } - }, - "jest-serializer": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-23.0.1.tgz", - "integrity": "sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=", - "dev": true - }, - "jest-snapshot": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-23.0.1.tgz", - "integrity": "sha1-ZnT6Gbnraamcq+zUFb3cQtavPn4=", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^23.0.1", - "jest-matcher-utils": "^23.0.1", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^23.0.1" - } - }, - "jest-util": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-23.1.0.tgz", - "integrity": "sha1-wCUbrzRkTG3S/qeKli9CY6xVdy0=", - "dev": true, - "requires": { - "callsites": "^2.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.11", - "is-ci": "^1.0.10", - "jest-message-util": "^23.1.0", - "mkdirp": "^0.5.1", - "slash": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "jest-validate": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.0.1.tgz", - "integrity": "sha1-zZ8BqJ0mu4hfEqhmdxXpyGWldU8=", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", - "leven": "^2.1.0", - "pretty-format": "^23.0.1" - } - }, - "jest-watcher": { - "version": "23.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-23.1.0.tgz", - "integrity": "sha1-qNWELjjZ+0r/+CPfartCpYrmzb0=", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "string-length": "^2.0.0" - } - }, - "jest-worker": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.0.1.tgz", - "integrity": "sha1-nmSd2WP/QEYCb5HEAX8Dmmqkp7w=", - "dev": true, - "requires": { - "merge-stream": "^1.0.1" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "jsdom": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz", - "integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==", - "dev": true, - "requires": { - "abab": "^1.0.4", - "acorn": "^5.3.0", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": ">= 0.3.1 < 0.4.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.0", - "escodegen": "^1.9.0", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.2.0", - "nwsapi": "^2.0.0", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.83.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.3", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^4.0.0", - "xml-name-validator": "^3.0.0" - } - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", - "dev": true - }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", - "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==", - "dev": true - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, - "requires": { - "js-tokens": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dev": true, - "requires": { - "tmpl": "1.0.x" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "math-random": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", - "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=", - "dev": true - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "merge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", - "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", - "dev": true - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "~1.33.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-notifier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", - "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", - "dev": true, - "requires": { - "growly": "^1.3.0", - "semver": "^5.4.1", - "shellwords": "^0.1.1", - "which": "^1.3.0" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "nwsapi": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.3.tgz", - "integrity": "sha512-zFJF9lOpg2+uicP0BQKOAfIOqeTp/p8PC669mewxgRkR1hGjne8BMUHk4wpRS9o5Z0icA5Nv04HmGkW31KfMKw==", - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-format": { - "version": "23.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.0.1.tgz", - "integrity": "sha1-1h0GUmjkx1kIO8y8onoBrXx2AfQ=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.1.27", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.27.tgz", - "integrity": "sha512-J8tJX5tAeEp9tQTI2w2aMZ6V1INuU4JmNaNPRuHAqjjVq3ZJ+jV3+tcT3ncgTnBxvwJy740IB/WZrxFus2VdMA==", - "dev": true - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "randomatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", - "dev": true, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "realpath-native": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.0.tgz", - "integrity": "sha512-XJtlRJ9jf0E1H1SLeJyQ9PGzQD7S65h1pRXEcAeK48doKOnKxcgPeNohJvD5u/2sI9J1oke6E8bZHS/fmW1UiQ==", - "dev": true, - "requires": { - "util.promisify": "^1.0.0" - } - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", - "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "requires": { - "punycode": "^1.4.1" - } - } - } - }, - "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", - "dev": true, - "requires": { - "lodash": "^4.13.1" - } - }, - "request-promise-native": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", - "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", - "dev": true, - "requires": { - "request-promise-core": "1.1.1", - "stealthy-require": "^1.1.0", - "tough-cookie": ">=2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "rsvp": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", - "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sane": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/sane/-/sane-2.5.2.tgz", - "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "capture-exit": "^1.2.0", - "exec-sh": "^0.2.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.3", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5", - "watch": "~0.18.0" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, - "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", - "dev": true, - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", - "dev": true - }, - "test-exclude": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", - "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "micromatch": "^3.1.8", - "object-assign": "^4.1.0", - "read-pkg-up": "^1.0.1", - "require-main-filename": "^1.0.1" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - } - } - }, - "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", - "dev": true - }, - "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "tough-cookie": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.2.tgz", - "integrity": "sha512-vahm+X8lSV/KjXziec8x5Vp0OTC9mq8EVCOApIsRAooeuMPSO8aT7PFACYkaL0yZ/3hVqw+8DzhCJwl8H2Ad6w==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "use": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", - "dev": true, - "requires": { - "browser-process-hrtime": "^0.1.2" - } - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "requires": { - "makeerror": "1.0.x" - } - }, - "watch": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", - "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", - "dev": true, - "requires": { - "exec-sh": "^0.2.0", - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", - "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.19" - } - }, - "whatwg-mimetype": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz", - "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==", - "dev": true - }, - "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "ws": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", - "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0" - } - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", - "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - } - } - }, - "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - } - } -} diff --git a/examples/apps/api-gateway-multiple-origin-cors/package.json b/examples/apps/api-gateway-multiple-origin-cors/package.json deleted file mode 100644 index d87477c793..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "cors-multiple-origin", - "version": "0.0.1", - "description": "Example of Multiple-Origin CORS using API Gateway and Lambda", - "main": "index.js", - "scripts": { - "test": "jest" - }, - "author": "", - "devDependencies": { - "jest": "^23.1.0", - "lodash": ">=4.17.13", - "merge": ">=1.2.1" - }, - "jest": { - "testPathIgnorePatterns": [ - "/node_modules/", - "/routes/test\\.js" - ] - } -} diff --git a/examples/apps/api-gateway-multiple-origin-cors/routes/root.js b/examples/apps/api-gateway-multiple-origin-cors/routes/root.js deleted file mode 100644 index 70923769f9..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/routes/root.js +++ /dev/null @@ -1,19 +0,0 @@ -const cors = require("../cors-util"); -const config = require("../cors-config.json"); - -/** - * Demonstrates a simple endpoint that accepts GET requests. - * - * In most cases, browsers do not perform CORS preflight requests when using - * the GET method, so we do not have to handle OPTIONS requests. - * Any desired additional CORS headers should be included in the GET response. - */ -exports.handler = async (event, context) => { - const origin = cors.getOriginFromEvent(event); - - // return an empty response, with CORS origin - return { - headers: cors.createOriginHeader(origin, config.allowedOrigins), - statusCode: 204 - }; -}; diff --git a/examples/apps/api-gateway-multiple-origin-cors/routes/test.js b/examples/apps/api-gateway-multiple-origin-cors/routes/test.js deleted file mode 100644 index 0676e15c8d..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/routes/test.js +++ /dev/null @@ -1,24 +0,0 @@ -const cors = require("../cors-util"); -const config = require("../cors-config.json"); - -/** - * Demonstrates an endpoint that accepts DELETE requests. - * - * In this case, the browser will perform a CORS preflight request, so we must - * handle OPTIONS requests and provide the CORS headers. - * When the browser makes the DELETE request, we only need to provide the origin. - */ -exports.handler = async (event, context) => { - const origin = cors.getOriginFromEvent(event); - const allowedMethods = ["OPTIONS", "DELETE"]; - - if (event.httpMethod === "OPTIONS") { - return cors.createPreflightResponse(origin, config.allowedOrigins, allowedMethods); - } else if (event.httpMethod === "DELETE") { - // return an empty response, with CORS origin - return { - headers: cors.createOriginHeader(origin, config.allowedOrigins), - statusCode: 204 - }; - } -}; diff --git a/examples/apps/api-gateway-multiple-origin-cors/template.yaml b/examples/apps/api-gateway-multiple-origin-cors/template.yaml deleted file mode 100644 index d900c9d834..0000000000 --- a/examples/apps/api-gateway-multiple-origin-cors/template.yaml +++ /dev/null @@ -1,50 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Example of Multiple-Origin CORS using API Gateway and Lambda' -Resources: - ExampleRoot: - Type: 'AWS::Serverless::Function' - Properties: - CodeUri: '.' - Handler: 'routes/root.handler' - Runtime: 'nodejs8.10' - Events: - Get: - Type: 'Api' - Properties: - Path: '/' - Method: 'get' - ExampleTest: - Type: 'AWS::Serverless::Function' - Properties: - CodeUri: '.' - Handler: 'routes/test.handler' - Runtime: 'nodejs8.10' - Events: - Delete: - Type: 'Api' - Properties: - Path: '/test' - Method: 'delete' - Options: - Type: 'Api' - Properties: - Path: '/test' - Method: 'options' - -Outputs: - ExampleApi: - Description: "API Gateway endpoint URL for Prod stage for API Gateway Multi-Origin CORS function" - Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/" - ExampleRoot: - Description: "API Gateway Multi-Origin CORS Lambda Function (Root) ARN" - Value: !GetAtt ExampleRoot.Arn - ExampleRootIamRole: - Description: "Implicit IAM Role created for API Gateway Multi-Origin CORS function (Root)" - Value: !GetAtt ExampleRootRole.Arn - ExampleTest: - Description: "API Gateway Multi-Origin CORS Lambda Function (Test) ARN" - Value: !GetAtt ExampleTest.Arn - ExampleTestIamRole: - Description: "Implicit IAM Role created for API Gateway Multi-Origin CORS function (Test)" - Value: !GetAtt ExampleTestRole.Arn diff --git a/examples/apps/cfn-look-up-ami-ids/index.js b/examples/apps/cfn-look-up-ami-ids/index.js deleted file mode 100644 index 3d5bf423b8..0000000000 --- a/examples/apps/cfn-look-up-ami-ids/index.js +++ /dev/null @@ -1,106 +0,0 @@ -'use strict'; - -/** - * A sample Lambda function that looks up the latest AMI ID for a given - * region and architecture. Make sure to include permissions for - * `ec2:DescribeImages` in your execution role! - * - * See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-custom-resources-lambda-lookup-amiids.html - * for documentation on how to use this blueprint. - */ -const aws = require('aws-sdk'); -const https = require('https'); -const url = require('url'); - -// Map instance architectures to an AMI name pattern -const archToAMINamePattern = { - PV64: 'amzn-ami-pv*.x86_64-ebs', - HVM64: 'amzn-ami-hvm*.x86_64-gp2', - HVMG2: 'amzn-ami-graphics-hvm-*x86_64-ebs*', -}; - -// Check if the image is a beta or RC image (the Lambda function won't return any of these images) -const isBeta = (imageName) => imageName.toLowerCase().includes('beta') || imageName.toLowerCase().includes('.rc'); - -// Sends a response to the pre-signed S3 URL -function sendResponse(event, callback, logStreamName, responseStatus, responseData) { - const responseBody = JSON.stringify({ - Status: responseStatus, - Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, - PhysicalResourceId: logStreamName, - StackId: event.StackId, - RequestId: event.RequestId, - LogicalResourceId: event.LogicalResourceId, - Data: responseData, - }); - - console.log('RESPONSE BODY:\n', responseBody); - - const parsedUrl = url.parse(event.ResponseURL); - const options = { - hostname: parsedUrl.hostname, - port: 443, - path: parsedUrl.path, - method: 'PUT', - headers: { - 'Content-Type': '', - 'Content-Length': responseBody.length, - }, - }; - - const req = https.request(options, (res) => { - console.log('STATUS:', res.statusCode); - console.log('HEADERS:', JSON.stringify(res.headers)); - callback(null, 'Successfully sent stack response!'); - }); - - req.on('error', (err) => { - console.log('sendResponse Error:\n', err); - callback(err); - }); - - req.write(responseBody); - req.end(); -} - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - - if (event.RequestType === 'Delete') { - sendResponse(event, callback, context.logStreamName, 'SUCCESS'); - return; - } - - let responseStatus = 'FAILED'; - let responseData = {}; - const ec2 = new aws.EC2({ region: event.ResourceProperties.Region }); - const describeImagesParams = { - Filters: [ - { - Name: 'name', - Values: [archToAMINamePattern[event.ResourceProperties.Architecture]], - }, - ], - Owners: [event.ResourceProperties.Architecture === 'HVMG2' ? '679593333241' : 'amazon'], - }; - - // Get AMI IDs with the specified name pattern and owner - ec2.describeImages(describeImagesParams, (err, data) => { - if (err) { - responseData = { Error: 'DescribeImages call failed' }; - console.log(`${responseData.Error}:\n`, err); - } else { - const images = data.Images; - // Sort images by name in descending order -- the names contain the AMI version formatted as YYYY.MM.Ver. - images.sort((x, y) => y.Name.localeCompare(x.Name)); - for (let i = 0; i < images.length; i++) { - if (!isBeta(images[i].Name)) { - responseStatus = 'SUCCESS'; - responseData.Id = images[i].ImageId; - break; - } - } - } - sendResponse(event, callback, context.logStreamName, responseStatus, responseData); - }); -}; diff --git a/examples/apps/cfn-look-up-ami-ids/package.json b/examples/apps/cfn-look-up-ami-ids/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cfn-look-up-ami-ids/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cfn-look-up-ami-ids/template.yaml b/examples/apps/cfn-look-up-ami-ids/template.yaml deleted file mode 100644 index 5ae40232ce..0000000000 --- a/examples/apps/cfn-look-up-ami-ids/template.yaml +++ /dev/null @@ -1,15 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Looks up the latest AMI ID for a given region and architecture. -Resources: - cfnlookupamiids: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Looks up the latest AMI ID for a given region and architecture. - MemorySize: 128 - Timeout: 3 - Policies: - - AMIDescribePolicy: {} \ No newline at end of file diff --git a/examples/apps/cfn-stack-outputs/index.js b/examples/apps/cfn-stack-outputs/index.js deleted file mode 100644 index f4b4e79457..0000000000 --- a/examples/apps/cfn-stack-outputs/index.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; - -/** - * A sample Lambda function that takes an AWS CloudFormation stack name - * and returns the outputs from that stack. Make sure to include permissions - * for `cloudformation:DescribeStacks` in your execution role! - * - * See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/walkthrough-custom-resources-lambda-cross-stack-ref.html - * for documentation on how to use this blueprint. - */ -const https = require('https'); -const url = require('url'); - -// Sends a response to the pre-signed S3 URL -function sendResponse(event, callback, logStreamName, responseStatus, responseData) { - const responseBody = JSON.stringify({ - Status: responseStatus, - Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, - PhysicalResourceId: logStreamName, - StackId: event.StackId, - RequestId: event.RequestId, - LogicalResourceId: event.LogicalResourceId, - Data: responseData, - }); - - console.log('RESPONSE BODY:\n', responseBody); - - const parsedUrl = url.parse(event.ResponseURL); - const options = { - hostname: parsedUrl.hostname, - port: 443, - path: parsedUrl.path, - method: 'PUT', - headers: { - 'Content-Type': '', - 'Content-Length': responseBody.length, - }, - }; - - const req = https.request(options, (res) => { - console.log('STATUS:', res.statusCode); - console.log('HEADERS:', JSON.stringify(res.headers)); - callback(null, 'Successfully sent stack response!'); - }); - - req.on('error', (err) => { - console.log('sendResponse Error:\n', err); - callback(err); - }); - - req.write(responseBody); - req.end(); -} - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - - if (event.RequestType === 'Delete') { - sendResponse(event, callback, context.logStreamName, 'SUCCESS'); - return; - } - - const stackName = event.ResourceProperties.StackName; - let responseStatus = 'FAILED'; - let responseData = {}; - - // Verifies that a stack name was passed - if (stackName) { - const aws = require('aws-sdk'); - - const cfn = new aws.CloudFormation(); - cfn.describeStacks({ StackName: stackName }, (err, data) => { - if (err) { - responseData = { Error: 'DescribeStacks call failed' }; - console.log(`${responseData.Error}:\n`, err); - } else { - // Populates the return data with the outputs from the specified stack - responseStatus = 'SUCCESS'; - data.Stacks[0].Outputs.forEach((output) => responseData[output.OutputKey] = output.OutputValue); - } - sendResponse(event, callback, context.logStreamName, responseStatus, responseData); - }); - } else { - responseData = { Error: 'Stack name not specified' }; - console.log(responseData.Error); - sendResponse(event, callback, context.logStreamName, responseStatus, responseData); - } -}; diff --git a/examples/apps/cfn-stack-outputs/package.json b/examples/apps/cfn-stack-outputs/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cfn-stack-outputs/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cfn-stack-outputs/template.yaml b/examples/apps/cfn-stack-outputs/template.yaml deleted file mode 100644 index 4d15e5e607..0000000000 --- a/examples/apps/cfn-stack-outputs/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Takes an AWS CloudFormation stack name and returns the outputs from that - stack. -Resources: - cfnstackoutputs: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Takes an AWS CloudFormation stack name and returns the outputs from that - stack. - MemorySize: 128 - Timeout: 3 - Policies: - - CloudFormationDescribeStacksPolicy: {} \ No newline at end of file diff --git a/examples/apps/cloudfront-ab-test/index.js b/examples/apps/cloudfront-ab-test/index.js deleted file mode 100644 index 5004c6e11b..0000000000 --- a/examples/apps/cloudfront-ab-test/index.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; - -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - const headers = request.headers; - - if (request.uri !== '/experiment-pixel.jpg') { - // do not process if this is not an A-B test request - callback(null, request); - return; - } - - const cookieExperimentA = 'X-Experiment-Name=A'; - const cookieExperimentB = 'X-Experiment-Name=B'; - const pathExperimentA = '/experiment-group/control-pixel.jpg'; - const pathExperimentB = '/experiment-group/treatment-pixel.jpg'; - - /* - * Lambda at the Edge headers are array objects. - * - * Client may send multiple Cookie headers, i.e.: - * > GET /viewerRes/test HTTP/1.1 - * > User-Agent: curl/7.18.1 (x86_64-unknown-linux-gnu) libcurl/7.18.1 OpenSSL/1.0.1u zlib/1.2.3 - * > Cookie: First=1; Second=2 - * > Cookie: ClientCode=abc - * > Host: example.com - * - * You can access the first Cookie header at headers["cookie"][0].value - * and the second at headers["cookie"][1].value. - * - * Header values are not parsed. In the example above, - * headers["cookie"][0].value is equal to "First=1; Second=2" - */ - let experimentUri; - if (headers.cookie) { - for (let i = 0; i < headers.cookie.length; i++) { - if (headers.cookie[i].value.indexOf(cookieExperimentA) >= 0) { - console.log('Experiment A cookie found'); - experimentUri = pathExperimentA; - break; - } else if (headers.cookie[i].value.indexOf(cookieExperimentB) >= 0) { - console.log('Experiment B cookie found'); - experimentUri = pathExperimentB; - break; - } - } - } - - if (!experimentUri) { - console.log('Experiment cookie has not been found. Throwing dice...'); - if (Math.random() < 0.75) { - experimentUri = pathExperimentA; - } else { - experimentUri = pathExperimentB; - } - } - - request.uri = experimentUri; - console.log(`Request uri set to "${request.uri}"`); - callback(null, request); -}; diff --git a/examples/apps/cloudfront-ab-test/template.yaml b/examples/apps/cloudfront-ab-test/template.yaml deleted file mode 100644 index f2ad3d9014..0000000000 --- a/examples/apps/cloudfront-ab-test/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Blueprint for CloudFront ab testing, implemented in NodeJS.' -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontabtest: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: 'Blueprint for CloudFront ab testing, implemented in NodeJS.' - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-ab-test/testEvent.json b/examples/apps/cloudfront-ab-test/testEvent.json deleted file mode 100644 index 8d3f7b11f0..0000000000 --- a/examples/apps/cloudfront-ab-test/testEvent.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "uri": "/experiment-pixel.jpg", - "method": "GET", - "clientIp": "2001:cdba::3257:9652", - "headers": { - "user-agent": [ - { - "key": "User-Agent", - "value": "Test Agent" - } - ], - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ], - "cookie": [ - { - "key": "Cookie", - "value": "SomeCookie=1; AnotherOne=A;" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-access-request-in-response/index.js b/examples/apps/cloudfront-access-request-in-response/index.js deleted file mode 100644 index 173c085fbf..0000000000 --- a/examples/apps/cloudfront-access-request-in-response/index.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - const response = event.Records[0].cf.response; - - /* - * Set the Content-Disposition Header based on the user-name request header - */ - if (request.headers['user-name']) { - response.headers['content-disposition'] = [{ - key: 'Content-Disposition', - value: `attachment; filename=${request.headers['user-name'][0].value}`, - }]; - console.log(`Add content disposition response header "${response.headers['content-disposition'][0].value}"`); - } - callback(null, response); -}; diff --git a/examples/apps/cloudfront-access-request-in-response/template.yaml b/examples/apps/cloudfront-access-request-in-response/template.yaml deleted file mode 100644 index e755cf1ecf..0000000000 --- a/examples/apps/cloudfront-access-request-in-response/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint for setting CloudFront response header based on value in the request header implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontaccessrequestinresponse: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for setting CloudFront response header based on value in the request header implemented in NodeJS. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-access-request-in-response/testEvent.json b/examples/apps/cloudfront-access-request-in-response/testEvent.json deleted file mode 100644 index 258a53b65f..0000000000 --- a/examples/apps/cloudfront-access-request-in-response/testEvent.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "headers": { - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ], - "user-name": [ - { - "key": "User-Name", - "value": "CloudFront" - } - ] - }, - "clientIp": "2001:cdba::3257:9652", - "uri": "/test", - "method": "GET" - }, - "response": { - "status": "200", - "statusDescription": "OK", - "headers": { - "x-cache": [ - { - "key": "X-Cache", - "value": "Hello from Cloudfront" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-http-redirect/index.js b/examples/apps/cloudfront-http-redirect/index.js deleted file mode 100644 index 77a898732f..0000000000 --- a/examples/apps/cloudfront-http-redirect/index.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -exports.handler = (event, context, callback) => { - - var response = { - "statusCode": 302, - "headers": { - "Location": "http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html" - }, - "body": "{}", - "isBase64Encoded": false - }; - callback(null, response); -}; - diff --git a/examples/apps/cloudfront-http-redirect/template.yaml b/examples/apps/cloudfront-http-redirect/template.yaml deleted file mode 100644 index 5239605e39..0000000000 --- a/examples/apps/cloudfront-http-redirect/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Blueprint for returning HTTP redirect implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfronthttpredirect: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Blueprint for returning HTTP redirect implemented in NodeJS. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-modify-querystring/index.js b/examples/apps/cloudfront-modify-querystring/index.js deleted file mode 100644 index 63f8c9c4ae..0000000000 --- a/examples/apps/cloudfront-modify-querystring/index.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; - -const querystring = require('querystring'); - -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - - /* When a request contains a query string key-value pair but the origin server - * expects the value in a header, you can use this Lambda function to - * convert the key-value pair to a header. Here's what the function does: - * 1. Parses the query string and gets the key-value pair. - * 2. Adds a header to the request using the key-value pair that the function got in step 1. - */ - - /* Parse request querystring to get javascript object */ - const params = querystring.parse(request.querystring); - - /* Move auth param from querystring to headers */ - const headerName = 'Auth-Header'; - request.headers[headerName.toLowerCase()] = [{ key: headerName, value: params.auth }]; - delete params.auth; - - /* Update request querystring */ - request.querystring = querystring.stringify(params); - - callback(null, request); -}; diff --git a/examples/apps/cloudfront-modify-querystring/template.yaml b/examples/apps/cloudfront-modify-querystring/template.yaml deleted file mode 100644 index 2b65862f47..0000000000 --- a/examples/apps/cloudfront-modify-querystring/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint to add a header based on the values in a key-value pair in a querynstring. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontmodifyquerystring: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint to add a header based on the values in a key-value pair in a query string. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-modify-querystring/testEvent.json b/examples/apps/cloudfront-modify-querystring/testEvent.json deleted file mode 100644 index c296040a16..0000000000 --- a/examples/apps/cloudfront-modify-querystring/testEvent.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "uri": "/test", - "querystring": "auth=test&foo=bar", - "method": "GET", - "clientIp": "2001:cdba::3257:9652", - "headers": { - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ], - "user-agent": [ - { - "key": "User-Agent", - "value": "Test Agent" - } - ], - "user-name": [ - { - "key": "User-Name", - "value": "aws-cloudfront" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-modify-response-header/index.js b/examples/apps/cloudfront-modify-response-header/index.js deleted file mode 100644 index d7fa6e3f8f..0000000000 --- a/examples/apps/cloudfront-modify-response-header/index.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -exports.handler = (event, context, callback) => { - const response = event.Records[0].cf.response; - const headers = response.headers; - - const headerNameSrc = 'X-Amz-Meta-Last-Modified'; - const headerNameDst = 'Last-Modified'; - - if (headers[headerNameSrc.toLowerCase()]) { - headers[headerNameDst.toLowerCase()] = [{ - key: headerNameDst, - value: headers[headerNameSrc.toLowerCase()][0].value, - }]; - console.log(`Response header "${headerNameDst}" was set to ` + - `"${headers[headerNameDst.toLowerCase()][0].value}"`); - } - - callback(null, response); -}; diff --git a/examples/apps/cloudfront-modify-response-header/template.yaml b/examples/apps/cloudfront-modify-response-header/template.yaml deleted file mode 100644 index 2276c30a12..0000000000 --- a/examples/apps/cloudfront-modify-response-header/template.yaml +++ /dev/null @@ -1,20 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Blueprint for modifying CloudFront response header implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontmodifyresponseheader: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for modifying CloudFront response header implemented in NodeJS. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-modify-response-header/testEvent.json b/examples/apps/cloudfront-modify-response-header/testEvent.json deleted file mode 100644 index 3e1b2f9f05..0000000000 --- a/examples/apps/cloudfront-modify-response-header/testEvent.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "response": { - "status": "200", - "statusDescription": "OK", - "headers": { - "vary": [ - { - "key": "Vary", - "value": "*" - } - ], - "last-modified": [ - { - "key": "Last-Modified", - "value": "2016-11-25" - } - ], - "x-amz-meta-last-modified": [ - { - "key": "X-Amz-Meta-Last-Modified", - "value": "2016-01-01" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/index.js b/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/index.js deleted file mode 100644 index a0a23ce45c..0000000000 --- a/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/index.js +++ /dev/null @@ -1,85 +0,0 @@ -'use strict'; - -const https = require('https'); - -/* - * Makes multiple remote calls to fetch forecast for each of the city - * mentioned in GET request from CloudFront/S3 and generates one aggregated - * custom response for origin request event. - * - * The forecast details for each city are present in following S3 locations - * as a text file. - * https://cloudfront-blueprints.s3.amazonaws.com/blueprints/cities/{city} - * - * For lower latency, we use a CloudFront distribition with the S3 bucket - * as an origin and fetch the forecast from the CloudFront cache of - * the closest edge location. - * https://d1itj4mrjr44ts.cloudfront.net/blueprints/cities/{city} - */ - -function getCityForecast(request) { - return new Promise((resolve, reject) => { - https.get(request.uri, (response) => { - let content = ''; - response.setEncoding('utf8'); - response.on('data', (chunk) => { content += chunk; }); - response.on('end', () => resolve({ city: request.city, forecast: content })); - }).on('error', e => reject(e)); - }); -} - -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - const citiesBaseUri = 'https://d1itj4mrjr44ts.cloudfront.net/blueprints/cities/'; - const uri = request.uri; - - console.log('Requested URI: ', uri); - - if (!uri.match('^/forecast/')) { - /* Not a forecast request, continue */ - callback(null, request); - } else { /* Forecast request*/ - /* Forcast format: /forecast/City1:City2:City3:City4 */ - const uriSplit = uri.split('/'); - - /* 0 is the host, 1 is 'forecast', the cities are in index 2 */ - const cities = uriSplit[2].split(':'); - - /* List to maintain forecast uri of individual city */ - const forecasts = []; - - cities.forEach((cityName) => { - const cityForecastUri = citiesBaseUri + cityName; - forecasts.push({ city: cityName, uri: cityForecastUri }); - }); - - /* Get forecast for requested cities */ - console.log('Getting forecasts for: ', forecasts); - - Promise.all(forecasts.map(getCityForecast)).then((ret) => { - console.log('Aggregating the responses:\n', ret); - const response = { - status: '200', /* Status signals this is a generated response */ - statusDescription: 'OK', - headers: { - 'cache-control': [{ - key: 'Cache-Control', - value: 'max-age=60', - }], - 'content-type': [{ - key: 'Content-Type', - value: 'application/json', - }], - 'content-encoding': [{ - key: 'Content-Encoding', - value: 'UTF-8', - }], - }, - body: JSON.stringify(ret, null, '\t'), - }; - - console.log('Generated response: ', JSON.stringify(response)); - callback(null, response); - }); - } -}; diff --git a/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/template.yaml b/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/template.yaml deleted file mode 100644 index 0ac38b1a94..0000000000 --- a/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint for generating aggregated response from multiple remote calls on origin-request trigger implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontmultipleremotecallsaggregateresponse: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for generating aggregated response from multiple remote calls on origin-request trigger implemented in NodeJS. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/testEvent.json b/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/testEvent.json deleted file mode 100644 index a3518e5259..0000000000 --- a/examples/apps/cloudfront-multiple-remote-calls-aggregate-response/testEvent.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "uri": "/forecast/Seattle:NewYork:Chicago:SanFrancisco", - "method": "GET", - "clientIp": "2001:cdba::3257:9652", - "headers": { - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ], - "user-agent": [ - { - "key": "User-Agent", - "value": "Test Agent" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-redirect-on-viewer-country/index.js b/examples/apps/cloudfront-redirect-on-viewer-country/index.js deleted file mode 100644 index b4d8f1e8d3..0000000000 --- a/examples/apps/cloudfront-redirect-on-viewer-country/index.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -/* This is an origin request function */ -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - const headers = request.headers; - - /* - * Based on the value of the CloudFront-Viewer-Country header, generate an - * HTTP status code 302 (Redirect) response, and return a country-specific - * URL in the Location header. - * NOTE: 1. You must configure your distribution to cache based on the - * CloudFront-Viewer-Country header. For more information, see - * http://docs.aws.amazon.com/console/cloudfront/cache-on-selected-headers - * 2. CloudFront adds the CloudFront-Viewer-Country header after the viewer - * request event. To use this example, you must create a trigger for the - * origin request event. - */ - let url = 'https://example.com/'; - if (headers['cloudfront-viewer-country']) { - const countryCode = headers['cloudfront-viewer-country'][0].value; - if (countryCode === 'TW') { - url = 'https://tw.example.com/'; - } else if (countryCode === 'US') { - url = 'https://us.example.com/'; - } - } - - const response = { - status: '302', - statusDescription: 'Found', - headers: { - location: [{ - key: 'Location', - value: url, - }], - }, - }; - callback(null, response); -}; diff --git a/examples/apps/cloudfront-redirect-on-viewer-country/template.yaml b/examples/apps/cloudfront-redirect-on-viewer-country/template.yaml deleted file mode 100644 index a414a01a6a..0000000000 --- a/examples/apps/cloudfront-redirect-on-viewer-country/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint for generating a redirect response based on the viewer country. Triggered by an origin-request. Implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontredirectonviewercountry: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for generating a redirect response based on the viewer country. Triggered by an origin-request. Implemented in NodeJS. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-redirect-on-viewer-country/testEvent.json b/examples/apps/cloudfront-redirect-on-viewer-country/testEvent.json deleted file mode 100644 index bfa6d15b6e..0000000000 --- a/examples/apps/cloudfront-redirect-on-viewer-country/testEvent.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "uri": "/test", - "method": "GET", - "clientIp": "2001:cdba::3257:9652", - "headers": { - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ], - "cloudfront-viewer-country": [ - { - "key": "CloudFront-Viewer-Country", - "value": "TW" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-redirect-unauthenticated-users/index.js b/examples/apps/cloudfront-redirect-unauthenticated-users/index.js deleted file mode 100644 index 996e900096..0000000000 --- a/examples/apps/cloudfront-redirect-unauthenticated-users/index.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; - -function parseCookies(headers) { - const parsedCookie = {}; - if (headers.cookie) { - headers.cookie[0].value.split(';').forEach((cookie) => { - if (cookie) { - const parts = cookie.split('='); - parsedCookie[parts[0].trim()] = parts[1].trim(); - } - }); - } - return parsedCookie; -} - -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - const headers = request.headers; - - /* Check for session-id in request cookie in viewer-request event, - * if session-id is absent, redirect the user to sign in page with original - * request sent as redirect_url in query params. - */ - - /* Check for session-id in cookie, if present then proceed with request */ - const parsedCookies = parseCookies(headers); - if (parsedCookies && parsedCookies['session-id']) { - callback(null, request); - } - - /* URI encode the original request to be sent as redirect_url in query params */ - const encodedRedirectUrl = encodeURIComponent(`https://${headers.host[0].value}${request.uri}?${request.querystring}`); - const response = { - status: '302', - statusDescription: 'Found', - headers: { - location: [{ - key: 'Location', - value: `http://www.example.com/signin?redirect_url=${encodedRedirectUrl}`, - }], - }, - }; - callback(null, response); -}; diff --git a/examples/apps/cloudfront-redirect-unauthenticated-users/package.json b/examples/apps/cloudfront-redirect-unauthenticated-users/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cloudfront-redirect-unauthenticated-users/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cloudfront-redirect-unauthenticated-users/template.yaml b/examples/apps/cloudfront-redirect-unauthenticated-users/template.yaml deleted file mode 100644 index 5828c9fff9..0000000000 --- a/examples/apps/cloudfront-redirect-unauthenticated-users/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint for redirecting unauthenticated users to sign-in page; triggered by CloudFront viewer-request event. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontredirectunauthenticatedusers: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for redirecting unauthenticated users to sign-in page; triggered by CloudFront viewer-request event. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-redirect-unauthenticated-users/testEvent.json b/examples/apps/cloudfront-redirect-unauthenticated-users/testEvent.json deleted file mode 100644 index 4f8e6ec1a5..0000000000 --- a/examples/apps/cloudfront-redirect-unauthenticated-users/testEvent.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "uri": "/test", - "method": "GET", - "querystring": "foo=bar", - "headers": { - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudfront-response-generation/index.js b/examples/apps/cloudfront-response-generation/index.js deleted file mode 100644 index 2994863e76..0000000000 --- a/examples/apps/cloudfront-response-generation/index.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -exports.handler = (event, context, callback) => { - /* - * Generate HTTP response using 200 status code with a simple body. - */ - const response = { - status: '200', - statusDescription: 'OK', - headers: { - vary: [{ - key: 'Vary', - value: '*', - }], - 'last-modified': [{ - key: 'Last-Modified', - value: '2017-01-13', - }], - }, - body: 'Example body generated by Lambda@Edge function.', - }; - - callback(null, response); -}; diff --git a/examples/apps/cloudfront-response-generation/template.yaml b/examples/apps/cloudfront-response-generation/template.yaml deleted file mode 100644 index c0c08cd421..0000000000 --- a/examples/apps/cloudfront-response-generation/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint for generating a response from viewer-request trigger implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontresponsegeneration: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for generating a response from viewer-request trigger implemented in NodeJS. - MemorySize: 128 - Timeout: 1 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-simple-remote-call/index.js b/examples/apps/cloudfront-simple-remote-call/index.js deleted file mode 100644 index 223121dcb6..0000000000 --- a/examples/apps/cloudfront-simple-remote-call/index.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; - -const https = require('https'); - -exports.handler = (event, context, callback) => { - const request = event.Records[0].cf.request; - - let username = 'Guest'; - if (request.headers['user-name']) { - username = request.headers['user-name'][0].value; - } - console.log(`username = ${username}`); - - /* - * Fetch the template from CloudFront/S3 and replace the - * placeholder with a custom user name. - * - * The HTML template is stored in S3 bucket: - * https://cloudfront-blueprints.s3.amazonaws.com/blueprints/template.html - * - * For lower latency, we use a CloudFront distribition with the S3 bucket - * as an origin and fetch the template from the CloudFront cache of - * the closest edge location. - */ - const templateUrl = 'https://d1itj4mrjr44ts.cloudfront.net/blueprints/template.html'; - https.get(templateUrl, (res) => { - let content = ''; - res.on('data', (chunk) => { content += chunk; }); - res.on('end', () => { - content = content.replace(/{{user-name}}/ig, username); - const response = { - status: '200', - statusDescription: 'OK', - body: content, - headers: { - vary: [{ - key: 'Vary', - value: '*', - }], - 'last-modified': [{ - key: 'Last-Modified', - value: '2017-01-13', - }], - }, - }; - console.log(`Generated response = ${response.body}`); - callback(null, response); - }); - }); -}; diff --git a/examples/apps/cloudfront-simple-remote-call/template.yaml b/examples/apps/cloudfront-simple-remote-call/template.yaml deleted file mode 100644 index be3a4d5f58..0000000000 --- a/examples/apps/cloudfront-simple-remote-call/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Blueprint for generating a response from origin-request trigger implemented in NodeJS. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudfrontsimpleremotecall: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Blueprint for generating a response from origin-request trigger - implemented in NodeJS. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudfront-simple-remote-call/testEvent.json b/examples/apps/cloudfront-simple-remote-call/testEvent.json deleted file mode 100644 index 1eaa48f926..0000000000 --- a/examples/apps/cloudfront-simple-remote-call/testEvent.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Records": [ - { - "cf": { - "config": { - "distributionId": "EXAMPLE" - }, - "request": { - "uri": "/test", - "method": "GET", - "clientIp": "2001:cdba::3257:9652", - "headers": { - "host": [ - { - "key": "Host", - "value": "d123.cf.net" - } - ], - "user-agent": [ - { - "key": "User-Agent", - "value": "Test Agent" - } - ], - "user-name": [ - { - "key": "User-Name", - "value": "aws-cloudfront" - } - ] - } - } - } - } - ] -} diff --git a/examples/apps/cloudwatch-alarm-to-slack-python/index.js b/examples/apps/cloudwatch-alarm-to-slack-python/index.js deleted file mode 100644 index 9ce2af53a2..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python/index.js +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Algorithmia Lambda Function - * - * Calls any algorithm in the Algorithmia marketplace - * Get an API key and free credits by creating an account at algorithmia.com - * For more documentation see: algorithmia.com/docs/clients/lambda - * - * - * Follow these steps to encrypt your Algorithmia API Key for use in this function: - * - * 1. Create a KMS key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - * - * 2. Encrypt the event collector token using the AWS CLI - * aws kms encrypt --key-id alias/ --plaintext "" - * - * 3. Copy the base-64 encoded, encrypted key (CiphertextBlob) to the kmsEncryptedApiKey variable - * - * 4. Give your function's role permission for the kms:Decrypt action. - * Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} - */ -'use strict'; - -const algorithmia = require('algorithmia'); -const AWS = require('aws-sdk'); - -let apiKey; - -// Enter the base-64 encoded, encrypted key (CiphertextBlob) -const kmsEncryptedApiKey = ''; - -/* - * Configure your function to interact -*/ -const processEvent = (event, context) => { - /* - * Step 1: Set the algorithm you want to call - * This may be any algorithm in the Algorithmia marketplace - */ - const algorithm = 'algo://demo/Hello'; // algorithmia.com/algorithms/demo/Hello - - /* - * Step 2: Use your event source to set inputData according to the algorithm's input format - * This demo example uses the S3 Object's name as inputData - */ - const inputData = event.Records[0].s3.object.key; // Example for algo://demo/Hello - - /* Advanced example: - * Create 200x50 thumbnails for S3 file events using algo://opencv/SmartThumbnail - * Algorithm expects input as [URL, WIDTH, HEIGHT] - * Output is a base64 encoding of the resulting PNG thumbnail - * - * var algorithm = "algo://opencv/SmartThumbnail" - * var s3 = new AWS.S3(); - * var bucket = event.Records[0].s3.bucket.name; - * var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")) ; - * var params = {Bucket: bucket, Key: key}; - * var signedUrl = s3.getSignedUrl('getObject', params); - * var inputData = [signedUrl, 200, 50]; - */ - - // Run the algorithm - const client = algorithmia(apiKey); - client.algo(algorithm).pipe(inputData).then((output) => { - if (output.error) { - console.log(`Error: ${output.error.message}`); - context.fail(output.error.message); - } else { - /* - * Step 3: Process the algorithm output here - * This demo example prints and succeeds with the algorithm result - */ - console.log(output); - context.succeed(output.result); - } - }); -}; - -/* - * This is the lambda entrypoint (no modification necessary) - * it ensures apiKey is set (decrypting kmsEncryptedApiKey if provided) - * and then calls processEvent with the same event and context - */ -exports.handler = (event, context) => { - if (kmsEncryptedApiKey && kmsEncryptedApiKey !== '') { - const encryptedBuf = new Buffer(kmsEncryptedApiKey, 'base64'); - const cipherText = { CiphertextBlob: encryptedBuf }; - - const kms = new AWS.KMS(); - kms.decrypt(cipherText, (err, data) => { - if (err) { - console.log(`Decrypt error: ${err}`); - context.fail(err); - } else { - apiKey = data.Plaintext.toString('ascii'); - processEvent(event, context); - } - }); - } else if (apiKey) { - processEvent(event, context); - } else { - context.fail('API Key has not been set.'); - } -}; - diff --git a/examples/apps/cloudwatch-alarm-to-slack-python/lambda_function.py b/examples/apps/cloudwatch-alarm-to-slack-python/lambda_function.py deleted file mode 100644 index cb0cb8fbc5..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python/lambda_function.py +++ /dev/null @@ -1,91 +0,0 @@ -''' -Follow these steps to configure the webhook in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Incoming WebHooks". - - 3. Choose the default channel where messages will be sent and click "Add Incoming WebHooks Integration". - - 4. Copy the webhook URL from the setup instructions and use it in the next section. - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the slackChannel environment variable - - Note: The Slack channel does not contain private info, so do NOT click encrypt - - 4. Paste into the kmsEncryptedHookUrl environment variable and click encrypt - - Note: You must exclude the protocol from the URL (e.g. "hooks.slack.com/services/abc123"). - - 5. Give your function's role permission for the kms:Decrypt action. - - Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} -''' -from __future__ import print_function - -import boto3 -import json -import logging -import os - -from base64 import b64decode -from urllib2 import Request, urlopen, URLError, HTTPError - - -# The base-64 encoded, encrypted key (CiphertextBlob) stored in the kmsEncryptedHookUrl environment variable -ENCRYPTED_HOOK_URL = os.environ['kmsEncryptedHookUrl'] -# The Slack channel to send a message to stored in the slackChannel environment variable -SLACK_CHANNEL = os.environ['slackChannel'] - -HOOK_URL = "https://" + boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext'] - -logger = logging.getLogger() -logger.setLevel(logging.INFO) - - -def lambda_handler(event, context): - logger.info("Event: " + str(event)) - message = json.loads(event['Records'][0]['Sns']['Message']) - logger.info("Message: " + str(message)) - - alarm_name = message['AlarmName'] - #old_state = message['OldStateValue'] - new_state = message['NewStateValue'] - reason = message['NewStateReason'] - - slack_message = { - 'channel': SLACK_CHANNEL, - 'text': "%s state is now %s: %s" % (alarm_name, new_state, reason) - } - - req = Request(HOOK_URL, json.dumps(slack_message)) - try: - response = urlopen(req) - response.read() - logger.info("Message posted to %s", slack_message['channel']) - except HTTPError as e: - logger.error("Request failed: %d %s", e.code, e.reason) - except URLError as e: - logger.error("Server connection failed: %s", e.reason) diff --git a/examples/apps/cloudwatch-alarm-to-slack-python/package.json b/examples/apps/cloudwatch-alarm-to-slack-python/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cloudwatch-alarm-to-slack-python/template.yaml b/examples/apps/cloudwatch-alarm-to-slack-python/template.yaml deleted file mode 100644 index f5adc211f1..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python/template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon SNS trigger that sends CloudWatch alarm notifications to Slack. -Parameters: - KeyIdParameter: - Type: String - slackChannelParameter: - Type: String - kmsEncryptedHookUrlParameter: - Type: String -Resources: - cloudwatchalarmtoslackpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon SNS trigger that sends CloudWatch alarm notifications to - Slack. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Events: - SNS1: - Type: SNS - Properties: - Topic: - Ref: SNSTopic1 - Environment: - Variables: - slackChannel: slackChannelParameter - kmsEncryptedHookUrl: kmsEncryptedHookUrlParameter - SNSTopic1: - Type: 'AWS::SNS::Topic' diff --git a/examples/apps/cloudwatch-alarm-to-slack-python3/index.js b/examples/apps/cloudwatch-alarm-to-slack-python3/index.js deleted file mode 100644 index 9ce2af53a2..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python3/index.js +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Algorithmia Lambda Function - * - * Calls any algorithm in the Algorithmia marketplace - * Get an API key and free credits by creating an account at algorithmia.com - * For more documentation see: algorithmia.com/docs/clients/lambda - * - * - * Follow these steps to encrypt your Algorithmia API Key for use in this function: - * - * 1. Create a KMS key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - * - * 2. Encrypt the event collector token using the AWS CLI - * aws kms encrypt --key-id alias/ --plaintext "" - * - * 3. Copy the base-64 encoded, encrypted key (CiphertextBlob) to the kmsEncryptedApiKey variable - * - * 4. Give your function's role permission for the kms:Decrypt action. - * Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} - */ -'use strict'; - -const algorithmia = require('algorithmia'); -const AWS = require('aws-sdk'); - -let apiKey; - -// Enter the base-64 encoded, encrypted key (CiphertextBlob) -const kmsEncryptedApiKey = ''; - -/* - * Configure your function to interact -*/ -const processEvent = (event, context) => { - /* - * Step 1: Set the algorithm you want to call - * This may be any algorithm in the Algorithmia marketplace - */ - const algorithm = 'algo://demo/Hello'; // algorithmia.com/algorithms/demo/Hello - - /* - * Step 2: Use your event source to set inputData according to the algorithm's input format - * This demo example uses the S3 Object's name as inputData - */ - const inputData = event.Records[0].s3.object.key; // Example for algo://demo/Hello - - /* Advanced example: - * Create 200x50 thumbnails for S3 file events using algo://opencv/SmartThumbnail - * Algorithm expects input as [URL, WIDTH, HEIGHT] - * Output is a base64 encoding of the resulting PNG thumbnail - * - * var algorithm = "algo://opencv/SmartThumbnail" - * var s3 = new AWS.S3(); - * var bucket = event.Records[0].s3.bucket.name; - * var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")) ; - * var params = {Bucket: bucket, Key: key}; - * var signedUrl = s3.getSignedUrl('getObject', params); - * var inputData = [signedUrl, 200, 50]; - */ - - // Run the algorithm - const client = algorithmia(apiKey); - client.algo(algorithm).pipe(inputData).then((output) => { - if (output.error) { - console.log(`Error: ${output.error.message}`); - context.fail(output.error.message); - } else { - /* - * Step 3: Process the algorithm output here - * This demo example prints and succeeds with the algorithm result - */ - console.log(output); - context.succeed(output.result); - } - }); -}; - -/* - * This is the lambda entrypoint (no modification necessary) - * it ensures apiKey is set (decrypting kmsEncryptedApiKey if provided) - * and then calls processEvent with the same event and context - */ -exports.handler = (event, context) => { - if (kmsEncryptedApiKey && kmsEncryptedApiKey !== '') { - const encryptedBuf = new Buffer(kmsEncryptedApiKey, 'base64'); - const cipherText = { CiphertextBlob: encryptedBuf }; - - const kms = new AWS.KMS(); - kms.decrypt(cipherText, (err, data) => { - if (err) { - console.log(`Decrypt error: ${err}`); - context.fail(err); - } else { - apiKey = data.Plaintext.toString('ascii'); - processEvent(event, context); - } - }); - } else if (apiKey) { - processEvent(event, context); - } else { - context.fail('API Key has not been set.'); - } -}; - diff --git a/examples/apps/cloudwatch-alarm-to-slack-python3/lambda_function.py b/examples/apps/cloudwatch-alarm-to-slack-python3/lambda_function.py deleted file mode 100644 index 6d832edbeb..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python3/lambda_function.py +++ /dev/null @@ -1,91 +0,0 @@ -''' -Follow these steps to configure the webhook in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Incoming WebHooks". - - 3. Choose the default channel where messages will be sent and click "Add Incoming WebHooks Integration". - - 4. Copy the webhook URL from the setup instructions and use it in the next section. - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the slackChannel environment variable - - Note: The Slack channel does not contain private info, so do NOT click encrypt - - 4. Paste into the kmsEncryptedHookUrl environment variable and click encrypt - - Note: You must exclude the protocol from the URL (e.g. "hooks.slack.com/services/abc123"). - - 5. Give your function's role permission for the kms:Decrypt action. - - Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} -''' - -import boto3 -import json -import logging -import os - -from base64 import b64decode -from urllib.request import Request, urlopen -from urllib.error import URLError, HTTPError - - -# The base-64 encoded, encrypted key (CiphertextBlob) stored in the kmsEncryptedHookUrl environment variable -ENCRYPTED_HOOK_URL = os.environ['kmsEncryptedHookUrl'] -# The Slack channel to send a message to stored in the slackChannel environment variable -SLACK_CHANNEL = os.environ['slackChannel'] - -HOOK_URL = "https://" + boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext'].decode('utf-8') - -logger = logging.getLogger() -logger.setLevel(logging.INFO) - - -def lambda_handler(event, context): - logger.info("Event: " + str(event)) - message = json.loads(event['Records'][0]['Sns']['Message']) - logger.info("Message: " + str(message)) - - alarm_name = message['AlarmName'] - #old_state = message['OldStateValue'] - new_state = message['NewStateValue'] - reason = message['NewStateReason'] - - slack_message = { - 'channel': SLACK_CHANNEL, - 'text': "%s state is now %s: %s" % (alarm_name, new_state, reason) - } - - req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8')) - try: - response = urlopen(req) - response.read() - logger.info("Message posted to %s", slack_message['channel']) - except HTTPError as e: - logger.error("Request failed: %d %s", e.code, e.reason) - except URLError as e: - logger.error("Server connection failed: %s", e.reason) diff --git a/examples/apps/cloudwatch-alarm-to-slack-python3/package.json b/examples/apps/cloudwatch-alarm-to-slack-python3/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python3/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cloudwatch-alarm-to-slack-python3/template.yaml b/examples/apps/cloudwatch-alarm-to-slack-python3/template.yaml deleted file mode 100644 index 5a731211b6..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack-python3/template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon SNS trigger that sends CloudWatch alarm notifications to Slack. -Parameters: - KeyIdParameter: - Type: String - slackChannelParameter: - Type: String - kmsEncryptedHookUrlParameter: - Type: String -Resources: - cloudwatchalarmtoslackpython3: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python3.6 - CodeUri: . - Description: >- - An Amazon SNS trigger that sends CloudWatch alarm notifications to - Slack. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Events: - SNS1: - Type: SNS - Properties: - Topic: - Ref: SNSTopic1 - Environment: - Variables: - slackChannel: slackChannelParameter - kmsEncryptedHookUrl: kmsEncryptedHookUrlParameter - SNSTopic1: - Type: 'AWS::SNS::Topic' diff --git a/examples/apps/cloudwatch-alarm-to-slack/index.js b/examples/apps/cloudwatch-alarm-to-slack/index.js deleted file mode 100644 index ed1deb6d1f..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack/index.js +++ /dev/null @@ -1,134 +0,0 @@ -'use strict'; - -/** - * Follow these steps to configure the webhook in Slack: - * - * 1. Navigate to https://.slack.com/services/new - * - * 2. Search for and select "Incoming WebHooks". - * - * 3. Choose the default channel where messages will be sent and click "Add Incoming WebHooks Integration". - * - * 4. Copy the webhook URL from the setup instructions and use it in the next section. - * - * - * To encrypt your secrets use the following steps: - * - * 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - * - * 2. Click the "Enable Encryption Helpers" checkbox - * - * 3. Paste into the kmsEncryptedHookUrl environment variable and click encrypt - * - * Note: You must exclude the protocol from the URL (e.g. "hooks.slack.com/services/abc123"). - * - * 4. Give your function's role permission for the kms:Decrypt action. - * Example: - -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] -} - - */ - -const AWS = require('aws-sdk'); -const url = require('url'); -const https = require('https'); - -// The base-64 encoded, encrypted key (CiphertextBlob) stored in the kmsEncryptedHookUrl environment variable -const kmsEncryptedHookUrl = process.env.kmsEncryptedHookUrl; -// The Slack channel to send a message to stored in the slackChannel environment variable -const slackChannel = process.env.slackChannel; -let hookUrl; - - -function postMessage(message, callback) { - const body = JSON.stringify(message); - const options = url.parse(hookUrl); - options.method = 'POST'; - options.headers = { - 'Content-Type': 'application/json', - 'Content-Length': Buffer.byteLength(body), - }; - - const postReq = https.request(options, (res) => { - const chunks = []; - res.setEncoding('utf8'); - res.on('data', (chunk) => chunks.push(chunk)); - res.on('end', () => { - if (callback) { - callback({ - body: chunks.join(''), - statusCode: res.statusCode, - statusMessage: res.statusMessage, - }); - } - }); - return res; - }); - - postReq.write(body); - postReq.end(); -} - -function processEvent(event, callback) { - const message = JSON.parse(event.Records[0].Sns.Message); - - const alarmName = message.AlarmName; - //var oldState = message.OldStateValue; - const newState = message.NewStateValue; - const reason = message.NewStateReason; - - const slackMessage = { - channel: slackChannel, - text: `${alarmName} state is now ${newState}: ${reason}`, - }; - - postMessage(slackMessage, (response) => { - if (response.statusCode < 400) { - console.info('Message posted successfully'); - callback(null); - } else if (response.statusCode < 500) { - console.error(`Error posting message to Slack API: ${response.statusCode} - ${response.statusMessage}`); - callback(null); // Don't retry because the error is due to a problem with the request - } else { - // Let Lambda retry - callback(`Server error when processing message: ${response.statusCode} - ${response.statusMessage}`); - } - }); -} - - -exports.handler = (event, context, callback) => { - if (hookUrl) { - // Container reuse, simply process the event with the key in memory - processEvent(event, callback); - } else if (kmsEncryptedHookUrl && kmsEncryptedHookUrl !== '') { - const encryptedBuf = new Buffer(kmsEncryptedHookUrl, 'base64'); - const cipherText = { CiphertextBlob: encryptedBuf }; - - const kms = new AWS.KMS(); - kms.decrypt(cipherText, (err, data) => { - if (err) { - console.log('Decrypt error:', err); - return callback(err); - } - hookUrl = `https://${data.Plaintext.toString('ascii')}`; - processEvent(event, callback); - }); - } else { - callback('Hook URL has not been set.'); - } -}; diff --git a/examples/apps/cloudwatch-alarm-to-slack/package.json b/examples/apps/cloudwatch-alarm-to-slack/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cloudwatch-alarm-to-slack/template.yaml b/examples/apps/cloudwatch-alarm-to-slack/template.yaml deleted file mode 100644 index dd316e1f2f..0000000000 --- a/examples/apps/cloudwatch-alarm-to-slack/template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon SNS trigger that sends CloudWatch alarm notifications to Slack. -Parameters: - KeyIdParameter: - Type: String - slackChannelParameter: - Type: String - kmsEncryptedHookUrlParameter: - Type: String -Resources: - cloudwatchalarmtoslack: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon SNS trigger that sends CloudWatch alarm notifications to - Slack. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Events: - SNS1: - Type: SNS - Properties: - Topic: - Ref: SNSTopic1 - Environment: - Variables: - slackChannel: slackChannelParameter - kmsEncryptedHookUrl: kmsEncryptedHookUrlParameter - SNSTopic1: - Type: 'AWS::SNS::Topic' diff --git a/examples/apps/cloudwatch-logs-process-data/index.js b/examples/apps/cloudwatch-logs-process-data/index.js deleted file mode 100644 index ecd92bd96b..0000000000 --- a/examples/apps/cloudwatch-logs-process-data/index.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -const zlib = require('zlib'); - -exports.handler = (event, context, callback) => { - const payload = new Buffer(event.awslogs.data, 'base64'); - zlib.gunzip(payload, (err, res) => { - if (err) { - return callback(err); - } - const parsed = JSON.parse(res.toString('utf8')); - console.log('Decoded payload:', JSON.stringify(parsed)); - callback(null, `Successfully processed ${parsed.logEvents.length} log events.`); - }); -}; diff --git a/examples/apps/cloudwatch-logs-process-data/package.json b/examples/apps/cloudwatch-logs-process-data/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cloudwatch-logs-process-data/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cloudwatch-logs-process-data/template.yaml b/examples/apps/cloudwatch-logs-process-data/template.yaml deleted file mode 100644 index bc080b60a3..0000000000 --- a/examples/apps/cloudwatch-logs-process-data/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A real-time consumer of log events ingested by an Amazon CloudWatch Logs log - group. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudwatchlogsprocessdata: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - A real-time consumer of log events ingested by an Amazon CloudWatch Logs - log group. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/cloudwatch-logs-to-loggly/index.js b/examples/apps/cloudwatch-logs-to-loggly/index.js deleted file mode 100644 index 43eb7d7d96..0000000000 --- a/examples/apps/cloudwatch-logs-to-loggly/index.js +++ /dev/null @@ -1,130 +0,0 @@ -'use strict'; - -/* - * To encrypt your secrets use the following steps: - * - * 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - * - * 2. Click the "Enable Encryption Helpers" checkbox - * - * 3. Paste into the kmsEncryptedCustomerToken environment variable and click encrypt -*/ - -const AWS = require('aws-sdk'); -const http = require('http'); -const zlib = require('zlib'); - - -// loggly url, token and tag configuration -// user needs to edit environment variables when creating function via blueprint -// logglyHostName, e.g. logs-01.loggly.com -// logglyTags, e.g. CloudWatch2Loggly -const logglyConfiguration = { - hostName: process.env.logglyHostName, - tags: process.env.logglyTags, -}; - -// use KMS to decrypt customer token in kmsEncryptedCustomerToken environment variable -const decryptParams = { - CiphertextBlob: new Buffer(process.env.kmsEncryptedCustomerToken, 'base64'), -}; - -const kms = new AWS.KMS({ apiVersion: '2014-11-01' }); - -kms.decrypt(decryptParams, (error, data) => { - if (error) { - logglyConfiguration.tokenInitError = error; - console.log(error); - } else { - logglyConfiguration.customerToken = data.Plaintext.toString('ascii'); - } -}); - -// entry point -exports.handler = (event, context, callback) => { - const payload = new Buffer(event.awslogs.data, 'base64'); - - // converts the event to a valid JSON object with the sufficient infomation required - function parseEvent(logEvent, logGroupName, logStreamName) { - return { - // remove '\n' character at the end of the event - message: logEvent.message.substring(0, logEvent.message.length - 1), - logGroupName, - logStreamName, - timestamp: new Date(logEvent.timestamp).toISOString(), - }; - } - - // joins all the events to a single event - // and sends to Loggly using bulk endpoint - function postEventsToLoggly(parsedEvents) { - if (!logglyConfiguration.customerToken) { - if (logglyConfiguration.tokenInitError) { - console.log('error in decrypt the token. Not retrying.'); - return callback(logglyConfiguration.tokenInitError); - } - console.log('Cannot flush logs since authentication token has not been initialized yet. Trying again in 100 ms.'); - setTimeout(() => postEventsToLoggly(parsedEvents), 100); - return; - } - - // get all the events, stringify them and join them - // with the new line character which can be sent to Loggly - // via bulk endpoint - const finalEvent = parsedEvents.map(JSON.stringify).join('\n'); - - // creating logglyURL at runtime, so that user can change the tag or customer token in the go - // by modifying the current script - // create request options to send logs - try { - const options = { - hostname: logglyConfiguration.hostName, - path: `/bulk/${logglyConfiguration.customerToken}/tag/${encodeURIComponent(logglyConfiguration.tags)}`, - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Content-Length': finalEvent.length, - }, - }; - - const req = http.request(options, (res) => { - res.on('data', (data) => { - const result = JSON.parse(data.toString()); - if (result.response === 'ok') { - callback(null, 'all events are sent to Loggly'); - } else { - console.log(result.response); - } - }); - res.on('end', () => { - console.log('No more data in response.'); - callback(); - }); - }); - - req.on('error', (err) => { - console.log('problem with request:', err.toString()); - callback(err); - }); - - // write data to request body - req.write(finalEvent); - req.end(); - } catch (ex) { - console.log(ex.message); - callback(ex.message); - } - } - - zlib.gunzip(payload, (error, result) => { - if (error) { - callback(error); - } else { - const resultParsed = JSON.parse(result.toString('ascii')); - const parsedEvents = resultParsed.logEvents.map((logEvent) => - parseEvent(logEvent, resultParsed.logGroup, resultParsed.logStream)); - - postEventsToLoggly(parsedEvents); - } - }); -}; diff --git a/examples/apps/cloudwatch-logs-to-loggly/package.json b/examples/apps/cloudwatch-logs-to-loggly/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cloudwatch-logs-to-loggly/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cloudwatch-logs-to-loggly/template.yaml b/examples/apps/cloudwatch-logs-to-loggly/template.yaml deleted file mode 100644 index 1e2f688153..0000000000 --- a/examples/apps/cloudwatch-logs-to-loggly/template.yaml +++ /dev/null @@ -1,24 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Sends logs from Cloudwatch logs to Loggly using a Lambda function. -Parameters: - KeyIdParameter: - Type: String -Resources: - cloudwatchlogstologgly: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Sends logs from Cloudwatch logs to Loggly using a Lambda function. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Environment: - Variables: - kmsEncryptedCustomerToken: - logglyTags: CloudWatch2Loggly - logglyHostName: diff --git a/examples/apps/cognito-sync-trigger/index.js b/examples/apps/cognito-sync-trigger/index.js deleted file mode 100644 index f6a6a1c8ed..0000000000 --- a/examples/apps/cognito-sync-trigger/index.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - const modifiedEvent = event; - - // Check for the event type - if (event.eventType === 'SyncTrigger') { - // Modify value for a key - if ('SampleKey1' in event.datasetRecords) { - modifiedEvent.datasetRecords.SampleKey1.newValue = 'ModifyValue1'; - modifiedEvent.datasetRecords.SampleKey1.op = 'replace'; - } - - // Remove a key - if ('SampleKey2' in event.datasetRecords) { - modifiedEvent.datasetRecords.SampleKey2.op = 'remove'; - } - - // Add a key - if (!('SampleKey3' in event.datasetRecords)) { - modifiedEvent.datasetRecords.SampleKey3 = { - newValue: 'ModifyValue3', - op: 'replace', - }; - } - } - - callback(null, modifiedEvent); -}; diff --git a/examples/apps/cognito-sync-trigger/package.json b/examples/apps/cognito-sync-trigger/package.json deleted file mode 100644 index 02d6a7da6c..0000000000 --- a/examples/apps/cognito-sync-trigger/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "algorithmia-blueprint", - "version": "1.0.0", - "private": true, - "dependencies": { - "algorithmia": "^0.3.9" - } -} diff --git a/examples/apps/cognito-sync-trigger/template.yaml b/examples/apps/cognito-sync-trigger/template.yaml deleted file mode 100644 index 3d91cd5477..0000000000 --- a/examples/apps/cognito-sync-trigger/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Cognito Sync trigger that modifies Cognito datasets based on the - incoming event. -Parameters: - KeyIdParameter: - Type: String -Resources: - cognitosynctrigger: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Cognito Sync trigger that modifies Cognito datasets based on - the incoming event. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter diff --git a/examples/apps/config-rule-change-triggered/index.js b/examples/apps/config-rule-change-triggered/index.js deleted file mode 100644 index c92c627e61..0000000000 --- a/examples/apps/config-rule-change-triggered/index.js +++ /dev/null @@ -1,132 +0,0 @@ -'use strict'; - -const aws = require('aws-sdk'); - -const config = new aws.ConfigService(); - - -// Helper function used to validate input -function checkDefined(reference, referenceName) { - if (!reference) { - throw new Error(`Error: ${referenceName} is not defined`); - } - return reference; -} - -// Check whether the message is OversizedConfigurationItemChangeNotification or not -function isOverSizedChangeNotification(messageType) { - checkDefined(messageType, 'messageType'); - return messageType === 'OversizedConfigurationItemChangeNotification'; -} - -// Get configurationItem using getResourceConfigHistory API. -function getConfiguration(resourceType, resourceId, configurationCaptureTime, callback) { - config.getResourceConfigHistory({ resourceType, resourceId, laterTime: new Date(configurationCaptureTime), limit: 1 }, (err, data) => { - if (err) { - callback(err, null); - } - const configurationItem = data.configurationItems[0]; - callback(null, configurationItem); - }); -} - -// Convert from the API model to the original invocation model -/*eslint no-param-reassign: ["error", { "props": false }]*/ -function convertApiConfiguration(apiConfiguration) { - apiConfiguration.awsAccountId = apiConfiguration.accountId; - apiConfiguration.ARN = apiConfiguration.arn; - apiConfiguration.configurationStateMd5Hash = apiConfiguration.configurationItemMD5Hash; - apiConfiguration.configurationItemVersion = apiConfiguration.version; - apiConfiguration.configuration = JSON.parse(apiConfiguration.configuration); - if ({}.hasOwnProperty.call(apiConfiguration, 'relationships')) { - for (let i = 0; i < apiConfiguration.relationships.length; i++) { - apiConfiguration.relationships[i].name = apiConfiguration.relationships[i].relationshipName; - } - } - return apiConfiguration; -} - -// Based on the type of message get the configuration item either from configurationItem in the invoking event or using the getResourceConfigHistiry API in getConfiguration function. -function getConfigurationItem(invokingEvent, callback) { - checkDefined(invokingEvent, 'invokingEvent'); - if (isOverSizedChangeNotification(invokingEvent.messageType)) { - const configurationItemSummary = checkDefined(invokingEvent.configurationItemSummary, 'configurationItemSummary'); - getConfiguration(configurationItemSummary.resourceType, configurationItemSummary.resourceId, configurationItemSummary.configurationItemCaptureTime, (err, apiConfigurationItem) => { - if (err) { - callback(err); - } - const configurationItem = convertApiConfiguration(apiConfigurationItem); - callback(null, configurationItem); - }); - } else { - checkDefined(invokingEvent.configurationItem, 'configurationItem'); - callback(null, invokingEvent.configurationItem); - } -} - -// Check whether the resource has been deleted. If it has, then the evaluation is unnecessary. -function isApplicable(configurationItem, event) { - checkDefined(configurationItem, 'configurationItem'); - checkDefined(event, 'event'); - const status = configurationItem.configurationItemStatus; - const eventLeftScope = event.eventLeftScope; - return (status === 'OK' || status === 'ResourceDiscovered') && eventLeftScope === false; -} - -// This is where it's determined whether the resource is compliant or not. -// In this example, we simply decide that the resource is compliant if it is an instance and its type matches the type specified as the desired type. -// If the resource is not an instance, then we deem this resource to be not applicable. (If the scope of the rule is specified to include only -// instances, this rule would never have been invoked.) -function evaluateChangeNotificationCompliance(configurationItem, ruleParameters) { - checkDefined(configurationItem, 'configurationItem'); - checkDefined(configurationItem.configuration, 'configurationItem.configuration'); - checkDefined(ruleParameters, 'ruleParameters'); - - if (configurationItem.resourceType !== 'AWS::EC2::Instance') { - return 'NOT_APPLICABLE'; - } else if (ruleParameters.desiredInstanceType === configurationItem.configuration.instanceType) { - return 'COMPLIANT'; - } - return 'NON_COMPLIANT'; -} - -// This is the handler that's invoked by Lambda -// Most of this code is boilerplate; use as is -exports.handler = (event, context, callback) => { - checkDefined(event, 'event'); - const invokingEvent = JSON.parse(event.invokingEvent); - const ruleParameters = JSON.parse(event.ruleParameters); - getConfigurationItem(invokingEvent, (err, configurationItem) => { - if (err) { - callback(err); - } - let compliance = 'NOT_APPLICABLE'; - const putEvaluationsRequest = {}; - if (isApplicable(configurationItem, event)) { - // Invoke the compliance checking function. - compliance = evaluateChangeNotificationCompliance(configurationItem, ruleParameters); - } - // Put together the request that reports the evaluation status - putEvaluationsRequest.Evaluations = [ - { - ComplianceResourceType: configurationItem.resourceType, - ComplianceResourceId: configurationItem.resourceId, - ComplianceType: compliance, - OrderingTimestamp: configurationItem.configurationItemCaptureTime, - }, - ]; - putEvaluationsRequest.ResultToken = event.resultToken; - - // Invoke the Config API to report the result of the evaluation - config.putEvaluations(putEvaluationsRequest, (error, data) => { - if (error) { - callback(error, null); - } else if (data.FailedEvaluations.length > 0) { - // Ends the function execution if any evaluation results are not successfully reported. - callback(JSON.stringify(data), null); - } else { - callback(null, data); - } - }); - }); -}; diff --git a/examples/apps/config-rule-change-triggered/template.yaml b/examples/apps/config-rule-change-triggered/template.yaml deleted file mode 100644 index 67c45586ec..0000000000 --- a/examples/apps/config-rule-change-triggered/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An AWS Config rule that is triggered by configuration changes to EC2 - instances. Checks instance types. -Resources: - configrulechangetriggered: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An AWS Config rule that is triggered by configuration changes to EC2 - instances. Checks instance types. - MemorySize: 128 - Timeout: 10 - Policies: - - AWSConfigRulesExecutionRole diff --git a/examples/apps/config-rule-periodic/index.js b/examples/apps/config-rule-periodic/index.js deleted file mode 100644 index 55fdda1361..0000000000 --- a/examples/apps/config-rule-periodic/index.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; - -const aws = require('aws-sdk'); // Loads the AWS SDK for JavaScript. - -const config = new aws.ConfigService(); // Constructs a service object to use the aws.ConfigService class. -const COMPLIANCE_STATES = { - COMPLIANT: 'COMPLIANT', - NON_COMPLIANT: 'NON_COMPLIANT', - NOT_APPLICABLE: 'NOT_APPLICABLE', -}; - - -// Checks whether the invoking event is ScheduledNotification -function isScheduledNotification(invokingEvent) { - return (invokingEvent.messageType === 'ScheduledNotification'); -} - -// Evaluates the configuration items in the snapshot and returns the compliance value to the handler. -function evaluateCompliance(maxCount, actualCount) { - return (actualCount > maxCount) ? COMPLIANCE_STATES.NON_COMPLIANT : COMPLIANCE_STATES.COMPLIANT; -} - -function countResourceTypes(applicableResourceType, nextToken, count, callback) { - config.listDiscoveredResources({ resourceType: applicableResourceType, nextToken }, (err, data) => { - if (err) { - return callback(err); - } - const updated = count + data.resourceIdentifiers.length; - if (data.nextToken) { - countResourceTypes(applicableResourceType, data.nextToken, updated, callback); - } else { - callback(null, updated); - } - }); -} - - -// Receives the event and context from AWS Lambda. You can copy this handler and use it in your own -// code with little or no change. -exports.handler = (event, context, callback) => { - // Parses the invokingEvent and ruleParameters values, which contain JSON objects passed as strings. - const invokingEvent = JSON.parse(event.invokingEvent); - const ruleParameters = JSON.parse(event.ruleParameters); - const resourceCount = 0; - - if (isScheduledNotification(invokingEvent)) { - countResourceTypes(ruleParameters.applicableResourceType, '', resourceCount, (err, count) => { - if (err) { - return callback(err); - } - // Initializes the request that contains the evaluation results. - const putEvaluationsRequest = { - Evaluations: [{ - // Applies the evaluation result to the AWS account published in the event. - ComplianceResourceType: 'AWS::::Account', - ComplianceResourceId: event.accountId, - ComplianceType: evaluateCompliance(ruleParameters.maxCount, count), - OrderingTimestamp: new Date(), - }], - ResultToken: event.resultToken, - }; - // Sends the evaluation results to AWS Config. - config.putEvaluations(putEvaluationsRequest, (putErr, data) => { - if (putErr) { - return callback(putErr); - } - if (data.FailedEvaluations.length > 0) { - // Ends the function execution if any evaluation results are not successfully reported - return callback(JSON.stringify(data)); - } - callback(null, data); - }); - }); - } else { - callback('Invoked for a notification other than Scheduled Notification... Ignoring.'); - } -}; diff --git a/examples/apps/config-rule-periodic/template.yaml b/examples/apps/config-rule-periodic/template.yaml deleted file mode 100644 index 528cc8aa76..0000000000 --- a/examples/apps/config-rule-periodic/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An AWS Config rule that is triggered periodically. Checks for a maximum number - of resources in your account. -Resources: - configruleperiodic: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An AWS Config rule that is triggered periodically. Checks for a maximum - number of resources in your account. - MemorySize: 128 - Timeout: 10 - Policies: - - AWSConfigRulesExecutionRole diff --git a/examples/apps/datadog-process-rds-metrics/lambda_function.py b/examples/apps/datadog-process-rds-metrics/lambda_function.py deleted file mode 100644 index 89d3b8f70d..0000000000 --- a/examples/apps/datadog-process-rds-metrics/lambda_function.py +++ /dev/null @@ -1,156 +0,0 @@ -''' -This function processes a RDS enhanced monitoring DATA_MESSAGE, coming from CloudWatch Logs -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - 2. Click the "Enable Encryption Helpers" checkbox - 3. Paste <{"api_key":"", "app_key":""}> into the kmsEncryptedKeys environment variable and click encrypt - 4. Give your function's role permission for the kms:Decrypt action. - Example: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "kms:Decrypt" - ], - "Resource": [ - "" - ] - } - ] - } -''' -from __future__ import print_function - -import os -import gzip -import json -import re -import time -import urllib -import urllib2 -from base64 import b64decode -from StringIO import StringIO - -import boto3 - -# retrieve datadog options from KMS -KMS_ENCRYPTED_KEYS = os.environ['kmsEncryptedKeys'] -kms = boto3.client('kms') -datadog_keys = json.loads(kms.decrypt(CiphertextBlob=b64decode(KMS_ENCRYPTED_KEYS))['Plaintext']) - -print('INFO Lambda function initialized, ready to send metrics') - - -def _process_rds_enhanced_monitoring_message(ts, message, account, region): - instance_id = message['instanceID'] - host_id = message['instanceResourceID'] - tags = [ - 'dbinstanceidentifier:%s' % instance_id, - 'aws_account:%s' % account, - 'engine:%s' % message["engine"], - ] - - # metrics generation - - uptime = 0 - uptime_msg = re.split(' days?, ', message['uptime']) - if len(uptime_msg) == 2: - uptime += 24 * 3600 * int(uptime_msg[0]) - uptime_day = uptime_msg[-1].split(':') - uptime += 3600 * int(uptime_day[0]) - uptime += 60 * int(uptime_day[1]) - uptime += int(uptime_day[2]) - stats.gauge('aws.rds.uptime', uptime, timestamp=ts, tags=tags, host=host_id) - - stats.gauge('aws.rds.virtual_cpus', message['numVCPUs'], timestamp=ts, tags=tags, host=host_id) - - stats.gauge('aws.rds.load.1', message['loadAverageMinute']['one'], timestamp=ts, tags=tags, host=host_id) - stats.gauge('aws.rds.load.5', message['loadAverageMinute']['five'], timestamp=ts, tags=tags, host=host_id) - stats.gauge('aws.rds.load.15', message['loadAverageMinute']['fifteen'], timestamp=ts, tags=tags, host=host_id) - - for namespace in ['cpuUtilization', 'memory', 'tasks', 'swap']: - for key, value in message[namespace].iteritems(): - stats.gauge('aws.rds.%s.%s' % (namespace.lower(), key), value, timestamp=ts, tags=tags, host=host_id) - - for network_stats in message['network']: - network_tag = ['interface:%s' % network_stats.pop('interface')] - for key, value in network_stats.iteritems(): - stats.gauge('aws.rds.network.%s' % key, value, timestamp=ts, tags=tags + network_tag, host=host_id) - - disk_stats = message['diskIO'][0] # we never expect to have more than one disk - for key, value in disk_stats.iteritems(): - stats.gauge('aws.rds.diskio.%s' % key, value, timestamp=ts, tags=tags, host=host_id) - - for fs_stats in message['fileSys']: - fs_tag = [ - 'name:%s' % fs_stats.pop('name'), - 'mountPoint:%s' % fs_stats.pop('mountPoint') - ] - for key, value in fs_stats.iteritems(): - stats.gauge('aws.rds.filesystem.%s' % key, value, timestamp=ts, tags=tags + fs_tag, host=host_id) - - for process_stats in message['processList']: - process_tag = [ - 'name:%s' % process_stats.pop('name'), - 'id:%s' % process_stats.pop('id') - ] - for key, value in process_stats.iteritems(): - stats.gauge('aws.rds.process.%s' % key, value, timestamp=ts, tags=tags + process_tag, host=host_id) - - -def lambda_handler(event, context): - ''' Process a RDS enhenced monitoring DATA_MESSAGE, - coming from CLOUDWATCH LOGS - ''' - # event is a dict containing a base64 string gzipped - event = json.loads(gzip.GzipFile(fileobj=StringIO(event['awslogs']['data'].decode('base64'))).read()) - - account = event['owner'] - region = context.invoked_function_arn.split(':', 4)[3] - - log_events = event['logEvents'] - - for log_event in log_events: - message = json.loads(log_event['message']) - ts = log_event['timestamp'] / 1000 - _process_rds_enhanced_monitoring_message(ts, message, account, region) - - stats.flush() - return {'Status': 'OK'} - - -# Helpers to send data to Datadog, inspired from https://github.com/DataDog/datadogpy - -class Stats(object): - - def __init__(self): - self.series = [] - - def gauge(self, metric, value, timestamp=None, tags=None, host=None): - base_dict = { - 'metric': metric, - 'points': [(int(timestamp or time.time()), value)], - 'type': 'gauge', - 'tags': tags, - } - if host: - base_dict.update({'host': host}) - self.series.append(base_dict) - - def flush(self): - metrics_dict = { - 'series': self.series, - } - self.series = [] - - creds = urllib.urlencode(datadog_keys) - data = json.dumps(metrics_dict) - url = '%s?%s' % (datadog_keys.get('api_host', 'https://app.datadoghq.com/api/v1/series'), creds) - req = urllib2.Request(url, data, {'Content-Type': 'application/json'}) - response = urllib2.urlopen(req) - print('INFO Submitted data with status {}'.format(response.getcode())) - -stats = Stats() diff --git a/examples/apps/datadog-process-rds-metrics/template.yaml b/examples/apps/datadog-process-rds-metrics/template.yaml deleted file mode 100644 index 819e9e1004..0000000000 --- a/examples/apps/datadog-process-rds-metrics/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Pushes RDS Enhanced metrics to Datadog. -Parameters: - KeyIdParameter: - Type: String -Resources: - datadogprocessrdsmetrics: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: Pushes RDS Enhanced metrics to Datadog. - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Environment: - Variables: - kmsEncryptedKeys: diff --git a/examples/apps/dynamodb-process-stream-python/lambda_function.py b/examples/apps/dynamodb-process-stream-python/lambda_function.py deleted file mode 100644 index 00fd15326e..0000000000 --- a/examples/apps/dynamodb-process-stream-python/lambda_function.py +++ /dev/null @@ -1,14 +0,0 @@ -from __future__ import print_function - -import json - -print('Loading function') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - for record in event['Records']: - print(record['eventID']) - print(record['eventName']) - print("DynamoDB Record: " + json.dumps(record['dynamodb'], indent=2)) - return 'Successfully processed {} records.'.format(len(event['Records'])) diff --git a/examples/apps/dynamodb-process-stream-python/template.yaml b/examples/apps/dynamodb-process-stream-python/template.yaml deleted file mode 100644 index 07e5e42733..0000000000 --- a/examples/apps/dynamodb-process-stream-python/template.yaml +++ /dev/null @@ -1,39 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon DynamoDB trigger that logs the updates made to a table. -Resources: - dynamodbprocessstreampython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: An Amazon DynamoDB trigger that logs the updates made to a table. - MemorySize: 128 - Timeout: 3 - Policies: - - AWSConfigRulesExecutionRole - Events: - DynamoDB1: - Type: DynamoDB - Properties: - Stream: - 'Fn::GetAtt': - - Table1 - - StreamArn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - Table1: - Type: 'AWS::DynamoDB::Table' - Properties: - AttributeDefinitions: - - AttributeName: id - AttributeType: S - KeySchema: - - AttributeName: id - KeyType: HASH - ProvisionedThroughput: - ReadCapacityUnits: 5 - WriteCapacityUnits: 5 - StreamSpecification: - StreamViewType: NEW_IMAGE diff --git a/examples/apps/dynamodb-process-stream-python3/index.js b/examples/apps/dynamodb-process-stream-python3/index.js deleted file mode 100644 index ea31168de7..0000000000 --- a/examples/apps/dynamodb-process-stream-python3/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Stream events from AWS DynamoDB Stream to Splunk - * - * This function streams AWS DynamoDB Stream events to Splunk using - * Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to stream events to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - let count = 0; - - event.Records.forEach((record) => { - console.log('DynamoDB Record: %j', record.dynamodb); - - /* Log event to Splunk - - Use optional 'context' argument to send Lambda metadata e.g. awsRequestId, functionName. - - Change to "logger.logWithTime(, item, context)" to explicitly set event timestamp */ - logger.log(record, context); - - /* Alternatively, UNCOMMENT logger call below if you want to override Splunk input settings */ - /* Log event to Splunk with any combination of explicit timestamp, index, source, sourcetype, and host. - - Complete list of input settings available at http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector */ - // logger.logEvent({ - // host: 'serverless', - // source: `lambda:${context.functionName}`, - // sourcetype: 'httpevent', - // index: 'main', - // event: record, - // }); - - count += 1; - }); - - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - console.log(`Successfully processed ${count} record(s).`); - callback(null, count); // Return number of records processed - } - }); -}; diff --git a/examples/apps/dynamodb-process-stream-python3/lambda_function.py b/examples/apps/dynamodb-process-stream-python3/lambda_function.py deleted file mode 100644 index c11ad140f5..0000000000 --- a/examples/apps/dynamodb-process-stream-python3/lambda_function.py +++ /dev/null @@ -1,13 +0,0 @@ - -import json - -print('Loading function') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - for record in event['Records']: - print(record['eventID']) - print(record['eventName']) - print("DynamoDB Record: " + json.dumps(record['dynamodb'], indent=2)) - return 'Successfully processed {} records.'.format(len(event['Records'])) diff --git a/examples/apps/dynamodb-process-stream-python3/lib/mysplunklogger.js b/examples/apps/dynamodb-process-stream-python3/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/dynamodb-process-stream-python3/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/dynamodb-process-stream-python3/template.yaml b/examples/apps/dynamodb-process-stream-python3/template.yaml deleted file mode 100644 index 2c153199df..0000000000 --- a/examples/apps/dynamodb-process-stream-python3/template.yaml +++ /dev/null @@ -1,38 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon DynamoDB trigger that logs the updates made to a table. -Resources: - dynamodbprocessstreampython3: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python3.6 - CodeUri: . - Description: An Amazon DynamoDB trigger that logs the updates made to a table. - MemorySize: 128 - Timeout: 3 - Policies: [] - Events: - DynamoDB1: - Type: DynamoDB - Properties: - Stream: - 'Fn::GetAtt': - - Table1 - - StreamArn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - Table1: - Type: 'AWS::DynamoDB::Table' - Properties: - AttributeDefinitions: - - AttributeName: id - AttributeType: S - KeySchema: - - AttributeName: id - KeyType: HASH - ProvisionedThroughput: - ReadCapacityUnits: 5 - WriteCapacityUnits: 5 - StreamSpecification: - StreamViewType: NEW_IMAGE diff --git a/examples/apps/dynamodb-process-stream/index.js b/examples/apps/dynamodb-process-stream/index.js deleted file mode 100644 index b954c5136b..0000000000 --- a/examples/apps/dynamodb-process-stream/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - event.Records.forEach((record) => { - console.log(record.eventID); - console.log(record.eventName); - console.log('DynamoDB Record: %j', record.dynamodb); - }); - callback(null, `Successfully processed ${event.Records.length} records.`); -}; diff --git a/examples/apps/dynamodb-process-stream/template.yaml b/examples/apps/dynamodb-process-stream/template.yaml deleted file mode 100644 index 5cb35d8d73..0000000000 --- a/examples/apps/dynamodb-process-stream/template.yaml +++ /dev/null @@ -1,39 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon DynamoDB trigger that logs the updates made to a table. -Resources: - dynamodbprocessstream: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: An Amazon DynamoDB trigger that logs the updates made to a table. - MemorySize: 128 - Timeout: 3 - Policies: - - AWSConfigRulesExecutionRole - Events: - DynamoDB1: - Type: DynamoDB - Properties: - Stream: - 'Fn::GetAtt': - - Table1 - - StreamArn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - Table1: - Type: 'AWS::DynamoDB::Table' - Properties: - AttributeDefinitions: - - AttributeName: id - AttributeType: S - KeySchema: - - AttributeName: id - KeyType: HASH - ProvisionedThroughput: - ReadCapacityUnits: 5 - WriteCapacityUnits: 5 - StreamSpecification: - StreamViewType: NEW_IMAGE diff --git a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/index.js b/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/index.js deleted file mode 100755 index dd1190699d..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/index.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ -exports.GreengrassInterfaceVersion = '1.3'; -exports.Lambda = require('./lambda'); -exports.IotData = require('./iotdata'); -exports.SecretsManager = require('./secretsmanager'); diff --git a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/iotdata.js b/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/iotdata.js deleted file mode 100755 index c40c80e42f..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/iotdata.js +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ - -const Buffer = require('buffer').Buffer; - -const Lambda = require('./lambda'); -const Util = require('./util'); -const GreengrassCommon = require('aws-greengrass-common-js'); - -const envVars = GreengrassCommon.envVars; -const MY_FUNCTION_ARN = envVars.MY_FUNCTION_ARN; -const SHADOW_FUNCTION_ARN = envVars.SHADOW_FUNCTION_ARN; -const ROUTER_FUNCTION_ARN = envVars.ROUTER_FUNCTION_ARN; - -class IotData { - constructor() { - this.lambda = new Lambda(); - } - - getThingShadow(params, callback) { - /* - * Call shadow lambda to obtain current shadow state. - * @param {object} params object contains parameters for the call - * REQUIRED: 'thingName' the name of the thing - */ - const thingName = Util.getRequiredParameter(params, 'thingName'); - if (thingName === undefined) { - callback(new Error('"thingName" is a required parameter.'), null); - return; - } - - const payload = ''; - this._shadowOperation('get', thingName, payload, callback); - } - - updateThingShadow(params, callback) { - /* - * Call shadow lambda to update current shadow state. - * @param {object} params object contains parameters for the call - * REQUIRED: 'thingName' the name of the thing - * 'payload' the state information in JSON format - */ - const thingName = Util.getRequiredParameter(params, 'thingName'); - if (thingName === undefined) { - callback(new Error('"thingName" is a required parameter.'), null); - return; - } - - const payload = Util.getRequiredParameter(params, 'payload'); - if (payload === undefined) { - callback(new Error('"payload" is a required parameter.'), null); - return; - } - - this._shadowOperation('update', thingName, payload, callback); - } - - deleteThingShadow(params, callback) { - /* - * Call shadow lambda to delete the shadow state. - * @param {object} params object contains parameters for the call - * REQUIRED: 'thingName' the name of the thing - */ - const thingName = Util.getRequiredParameter(params, 'thingName'); - if (thingName === undefined) { - callback(new Error('"thingName" is a required parameter.'), null); - return; - } - - const payload = ''; - this._shadowOperation('delete', thingName, payload, callback); - } - - publish(params, callback) { - /* - * Publishes state information. - * @param {object} params object contains parameters for the call - * REQUIRED: 'topic' the topic name to be published - * 'payload' the state information in JSON format - */ - const topic = Util.getRequiredParameter(params, 'topic'); - if (topic === undefined) { - callback(new Error('"topic" is a required parameter'), null); - return; - } - - const payload = Util.getRequiredParameter(params, 'payload'); - if (payload === undefined) { - callback(new Error('"payload" is a required parameter'), null); - return; - } - - const context = { - custom: { - source: MY_FUNCTION_ARN, - subject: topic, - }, - }; - - const buff = Buffer.from(JSON.stringify(context)); - const clientContext = buff.toString('base64'); - - const invokeParams = { - FunctionName: ROUTER_FUNCTION_ARN, - InvocationType: 'Event', - ClientContext: clientContext, - Payload: payload, - }; - - console.log(`Publishing message on topic "${topic}" with Payload "${payload}"`); - - this.lambda.invoke(invokeParams, (err, data) => { - if (err) { - callback(err, null); // an error occurred - } else { - callback(null, data); // successful response - } - }); - } - - _shadowOperation(operation, thingName, payload, callback) { - const topic = `$aws/things/${thingName}/shadow/${operation}`; - const context = { - custom: { - subject: topic, - }, - }; - - const clientContext = Buffer.from(JSON.stringify(context)).toString('base64'); - const invokeParams = { - FunctionName: SHADOW_FUNCTION_ARN, - ClientContext: clientContext, - Payload: payload, - }; - - console.log(`Calling shadow service on topic "${topic}" with payload "${payload}"`); - this.lambda.invoke(invokeParams, (err, data) => { - if (err) { - callback(err, null); - } else { - callback(null, data); - } - }); - } -} - -module.exports = IotData; diff --git a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/lambda.js b/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/lambda.js deleted file mode 100755 index 1380b93d1e..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/lambda.js +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ - -const Util = require('./util'); -const IPCClient = require('aws-greengrass-ipc-sdk-js'); -const GreengrassCommon = require('aws-greengrass-common-js'); -const logging = require('aws-greengrass-common-js').logging; - -const AUTH_TOKEN = GreengrassCommon.envVars.AUTH_TOKEN; - -const logger = new logging.LocalWatchLogger(); - -class Lambda { - constructor() { - this.ipc = new IPCClient(AUTH_TOKEN); - } - - invoke(params, callback) { - const functionName = Util.getRequiredParameter(params, 'FunctionName'); - if (functionName === undefined) { - callback(new Error('"FunctionName" is a required parameter'), null); - return; - } - - let arnFields; - try { - arnFields = new GreengrassCommon.FunctionArnFields(functionName); - } catch (e) { - callback(new Error(`FunctionName is malformed: ${e}`), null); - return; - } - - let invocationType; - if (params.InvocationType === undefined || params.InvocationType === null) { - invocationType = 'RequestResponse'; - } else { - invocationType = params.InvocationType; - } - - if (invocationType !== 'Event' && invocationType !== 'RequestResponse') { - callback(new Error(`InvocationType '${invocationType}' is incorrect, should be 'Event' or 'RequestResponse'`), null); - return; - } - - const clientContext = params.ClientContext ? params.ClientContext : ''; - const payload = params.Payload; - const qualifier = params.Qualifier; - - if (!Util.isValidQualifier(qualifier)) { - callback(new Error(`Qualifier '${qualifier}' is incorrect`), null); - return; - } - - const qualifierInternal = arnFields.qualifier; - - // generate the right full function arn with qualifier - if (qualifierInternal && qualifier && qualifierInternal !== qualifier) { - callback(new Error(`Qualifier '${qualifier}' does not match the version in FunctionName`), null); - return; - } - - const finalQualifier = qualifierInternal === undefined || qualifierInternal == null ? qualifier : qualifierInternal; - - let functionArn; - if (typeof GreengrassCommon.buildFunctionArn === 'function') { - // GGC v1.9.0 or newer - functionArn = GreengrassCommon.buildFunctionArn( - arnFields.unqualifiedArn, - finalQualifier); - } else { - // older version of GGC - throw new Error('Function buildFunctionArn not found. buildFunctionArn is introduced in GGC v1.9.0. ' + - 'Please check your GGC version.'); - } - - // verify client context is base64 encoded - if (Object.prototype.hasOwnProperty.call(params, 'ClientContext')) { - const cxt = params.ClientContext; - if (!Util.isValidContext(cxt)) { - callback(new Error('Client Context is invalid'), null); - return; - } - } - - logger.debug(`Invoking local lambda ${functionArn} with payload ${payload} and client context ${clientContext}`); - - this.ipc.postWork(functionArn, payload, clientContext, invocationType, (postWorkErr, invocationId) => { - if (postWorkErr) { - logger.error(`Failed to invoke function due to ${postWorkErr}`); - callback(postWorkErr, null); - return; - } - - if (invocationType === 'RequestResponse') { - this.ipc.getWorkResult(functionArn, invocationId, (getWorkResultErr, body, functionErr, statusCode) => { - if (getWorkResultErr) { - logger.error(`Failed to get work result due to ${getWorkResultErr}`); - callback(getWorkResultErr, null); - return; - } - const data = { - FunctionError: functionErr, - StatusCode: statusCode, - Payload: body, - }; - callback(null, data); - }); - } else { - callback(null, invocationId); - } - }); - } -} - -module.exports = Lambda; diff --git a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/secretsmanager.js b/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/secretsmanager.js deleted file mode 100755 index 80a7c15493..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/secretsmanager.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ -const Buffer = require('buffer').Buffer; - -const Lambda = require('./lambda'); -const Util = require('./util'); -const GreengrassCommon = require('aws-greengrass-common-js'); - -const KEY_SECRET_ID = 'SecretId'; -const KEY_VERSION_ID = 'VersionId'; -const KEY_VERSION_STAGE = 'VersionStage'; -const KEY_SECRET_ARN = 'ARN'; -const KEY_SECRET_NAME = 'Name'; -const KEY_CREATED_DATE = 'CreatedDate'; - -const envVars = GreengrassCommon.envVars; -const SECRETS_MANAGER_FUNCTION_ARN = envVars.SECRETS_MANAGER_FUNCTION_ARN; - -class SecretsManager { - constructor() { - this.lambda = new Lambda(); - } - - getSecretValue(params, callback) { - const secretId = Util.getRequiredParameter(params, KEY_SECRET_ID); - const versionId = Util.getRequiredParameter(params, KEY_VERSION_ID); - const versionStage = Util.getRequiredParameter(params, KEY_VERSION_STAGE); - - if (secretId === undefined) { - callback(new Error(`"${KEY_SECRET_ID}" is a required parameter`), null); - return; - } - // TODO: Remove this once we support query by VersionId - if (versionId !== undefined) { - callback(new Error('Query by VersionId is not yet supported'), null); - return; - } - if (versionId !== undefined && versionStage !== undefined) { - callback(new Error('VersionId and VersionStage cannot both be specified at the same time'), null); - return; - } - - const getSecretValueRequestBytes = - SecretsManager._generateGetSecretValueRequestBytes(secretId, versionId, versionStage); - - const invokeParams = { - FunctionName: SECRETS_MANAGER_FUNCTION_ARN, - Payload: getSecretValueRequestBytes, - }; - - console.log(`Getting secret value from secrets manager: ${getSecretValueRequestBytes}`); - - this.lambda.invoke(invokeParams, (err, data) => { - if (err) { - callback(err, null); // an error occurred - } else if (SecretsManager._is200Response(data.Payload)) { - callback(null, data.Payload); // successful response - } else { - callback(new Error(JSON.stringify(data.Payload)), null); // error response - } - }); - } - - static _generateGetSecretValueRequestBytes(secretId, versionId, versionStage) { - const request = { - SecretId: secretId, - }; - - if (versionStage !== undefined) { - request.VersionStage = versionStage; - } - - if (versionId !== undefined) { - request.VersionId = versionId; - } - - return Buffer.from(JSON.stringify(request)); - } - - static _is200Response(payload) { - const hasSecretArn = this._stringContains(payload, KEY_SECRET_ARN); - const hasSecretName = this._stringContains(payload, KEY_SECRET_NAME); - const hasVersionId = this._stringContains(payload, KEY_VERSION_ID); - const hasCreatedDate = this._stringContains(payload, KEY_CREATED_DATE); - - return hasSecretArn && hasSecretName && hasVersionId && hasCreatedDate; - } - - static _stringContains(src, target) { - return src.indexOf(target) > -1; - } -} - -module.exports = SecretsManager; diff --git a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/util.js b/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/util.js deleted file mode 100755 index b02fa8e65d..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/aws-greengrass-core-sdk/util.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ - -const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; -const qualifierRegex = /(|[a-zA-Z0-9$_-]+)/; - -exports.getRequiredParameter = function _getRequiredParameter(params, requiredParam) { - if (!Object.prototype.hasOwnProperty.call(params, requiredParam)) { - return; - } - return params[requiredParam]; -}; - -exports.isValidJSON = function _isValidJSON(str) { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; -}; - -exports.isValidContext = function _isValidContext(context) { - if (!base64Regex.test(context)) { - return false; - } - try { - JSON.stringify(context); - } catch (e) { - return false; - } - return true; -}; - -exports.isValidQualifier = function _isValidQualifier(qualifier) { - if (!qualifierRegex.test(qualifier)) { - return false; - } - return true; -}; diff --git a/examples/apps/greengrass-hello-world-nodejs/index.js b/examples/apps/greengrass-hello-world-nodejs/index.js deleted file mode 100644 index 041a05babc..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/index.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - */ - -/* - * Demonstrates a simple publish to a topic using Greengrass Core NodeJS SDK - * This lambda function will retrieve underlying platform information and send - * a hello world message along with the platform information to the topic - * 'hello/world'. The function will sleep for five seconds, then repeat. - * Since the function is long-lived it will run forever when deployed to a - * Greengrass core. - */ - -const ggSdk = require('aws-greengrass-core-sdk'); - -const iotClient = new ggSdk.IotData(); -const os = require('os'); -const util = require('util'); - -function publishCallback(err, data) { - console.log('Publish response: '+data); - console.log('Publish error: '+err); -} - -const myPlatform = util.format('%s-%s', os.platform(), os.release()); -const pubOpt = { - topic: 'hello/world', - payload: JSON.stringify({ message: util.format('Hello world! Sent from Greengrass Core running on platform: %s using NodeJS', myPlatform) }), -}; - -function greengrassHelloWorldRun() { - iotClient.publish(pubOpt, publishCallback); -} - -// Schedule the job to run every 5 seconds -setInterval(greengrassHelloWorldRun, 5000); - -// This is a handler which does nothing for this example -exports.handler = function handler(event, context) { - console.log(event); - console.log(context); -}; diff --git a/examples/apps/greengrass-hello-world-nodejs/license/license.txt b/examples/apps/greengrass-hello-world-nodejs/license/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/license/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/greengrass-hello-world-nodejs/template.yaml b/examples/apps/greengrass-hello-world-nodejs/template.yaml deleted file mode 100644 index 65e3052a31..0000000000 --- a/examples/apps/greengrass-hello-world-nodejs/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Deploy this lambda to a Greengrass core where it will send a hello world - message to a topic -Parameters: - IdentityNameParameter: - Type: String -Resources: - greengrasshelloworldnodejs: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Deploy this lambda to a Greengrass core where it will send a hello world - message to a topic - MemorySize: 128 - Timeout: 3 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter diff --git a/examples/apps/greengrass-hello-world/greengrassHelloWorld.py b/examples/apps/greengrass-hello-world/greengrassHelloWorld.py deleted file mode 100644 index be838e3853..0000000000 --- a/examples/apps/greengrass-hello-world/greengrassHelloWorld.py +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - -# greengrassHelloWorld.py -# Demonstrates a simple publish to a topic using Greengrass core sdk -# This lambda function will retrieve underlying platform information and send -# a hello world message along with the platform information to the topic 'hello/world' -# The function will sleep for five seconds, then repeat. Since the function is -# long-lived it will run forever when deployed to a Greengrass core. The handler -# will NOT be invoked in our example since the we are executing an infinite loop. - -import logging -import greengrasssdk -import platform -from threading import Timer - - -# Creating a greengrass core sdk client -client = greengrasssdk.client('iot-data') - -# Retrieving platform information to send from Greengrass Core -my_platform = platform.platform() -if not my_platform: - payload_str = 'Hello world! Sent from Greengrass Core.' -else: - payload_str = 'Hello world! Sent from Greengrass Core running on platform: {}'.format(my_platform) - - -# When deployed to a Greengrass core, this code will be executed immediately -# as a long-lived lambda function. The code will enter the infinite while loop -# below. -# If you execute a 'test' on the Lambda Console, this test will fail by hitting the -# execution timeout of three seconds. This is expected as this function never returns -# a result. - -def greengrass_hello_world_run(): - try: - response = client.publish(topic='hello/world', payload=payload_str) - except Exception as e: - logging.error("Failed to publish the message, error: {}".format(e)) - else: - logging.info("Successfully publish the message, response: {}".format(response)) - - # Asynchronously schedule this function to be run again in 5 seconds - Timer(5, greengrass_hello_world_run).start() - - -# Execute the function above -greengrass_hello_world_run() - - -# This is a dummy handler and will not be invoked -# Instead the code above will be executed in an infinite loop for our example -def function_handler(event, context): - return diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/IoTDataPlane.py b/examples/apps/greengrass-hello-world/greengrasssdk/IoTDataPlane.py deleted file mode 100755 index a04bd6d5c1..0000000000 --- a/examples/apps/greengrass-hello-world/greengrasssdk/IoTDataPlane.py +++ /dev/null @@ -1,154 +0,0 @@ -# -# Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - -import base64 -import json -import logging - -from greengrasssdk import Lambda -from greengrass_common.env_vars import SHADOW_FUNCTION_ARN, ROUTER_FUNCTION_ARN, MY_FUNCTION_ARN - -# Log messages in the SDK are part of customer's log because they're helpful for debugging -# customer's lambdas. Since we configured the root logger to log to customer's log and set the -# propagate flag of this logger to True. The log messages submitted from this logger will be -# sent to the customer's local Cloudwatch handler. -customer_logger = logging.getLogger(__name__) -customer_logger.propagate = True - - -class ShadowError(Exception): - pass - - -class Client: - def __init__(self): - self.lambda_client = Lambda.Client() - - def get_thing_shadow(self, **kwargs): - r""" - Call shadow lambda to obtain current shadow state. - - :Keyword Arguments: - * *thingName* (``string``) -- - [REQUIRED] - The name of the thing. - - :returns: (``dict``) -- - The output from the GetThingShadow operation - * *payload* (``bytes``) -- - The state information, in JSON format. - """ - thing_name = self._get_required_parameter('thingName', **kwargs) - payload = b'' - - return self._shadow_op('get', thing_name, payload) - - def update_thing_shadow(self, **kwargs): - r""" - Updates the thing shadow for the specified thing. - - :Keyword Arguments: - * *thingName* (``string``) -- - [REQUIRED] - The name of the thing. - * *payload* (``bytes or seekable file-like object``) -- - [REQUIRED] - The state information, in JSON format. - - :returns: (``dict``) -- - The output from the UpdateThingShadow operation - * *payload* (``bytes``) -- - The state information, in JSON format. - """ - thing_name = self._get_required_parameter('thingName', **kwargs) - payload = self._get_required_parameter('payload', **kwargs) - - return self._shadow_op('update', thing_name, payload) - - def delete_thing_shadow(self, **kwargs): - r""" - Deletes the thing shadow for the specified thing. - - :Keyword Arguments: - * *thingName* (``string``) -- - [REQUIRED] - The name of the thing. - - :returns: (``dict``) -- - The output from the DeleteThingShadow operation - * *payload* (``bytes``) -- - The state information, in JSON format. - """ - thing_name = self._get_required_parameter('thingName', **kwargs) - payload = b'' - - return self._shadow_op('delete', thing_name, payload) - - def publish(self, **kwargs): - r""" - Publishes state information. - - :Keyword Arguments: - * *topic* (``string``) -- - [REQUIRED] - The name of the MQTT topic. - * *payload* (``bytes or seekable file-like object``) -- - The state information, in JSON format. - - :returns: None - """ - - topic = self._get_required_parameter('topic', **kwargs) - - # payload is an optional parameter - payload = kwargs.get('payload', b'') - - function_arn = ROUTER_FUNCTION_ARN - client_context = { - 'custom': { - 'source': MY_FUNCTION_ARN, - 'subject': topic - } - } - - customer_logger.debug('Publishing message on topic "{}" with Payload "{}"'.format(topic, payload)) - self.lambda_client._invoke_internal( - function_arn, - payload, - base64.b64encode(json.dumps(client_context).encode()), - 'Event' - ) - - def _get_required_parameter(self, parameter_name, **kwargs): - if parameter_name not in kwargs: - raise ValueError('Parameter "{parameter_name}" is a required parameter but was not provided.'.format( - parameter_name=parameter_name - )) - return kwargs[parameter_name] - - def _shadow_op(self, op, thing_name, payload): - topic = '$aws/things/{thing_name}/shadow/{op}'.format(thing_name=thing_name, op=op) - function_arn = SHADOW_FUNCTION_ARN - client_context = { - 'custom': { - 'subject': topic - } - } - - customer_logger.debug('Calling shadow service on topic "{}" with payload "{}"'.format(topic, payload)) - response = self.lambda_client._invoke_internal( - function_arn, - payload, - base64.b64encode(json.dumps(client_context).encode()) - ) - - payload = response['Payload'].read() - if response: - response_payload_map = json.loads(payload.decode('utf-8')) - if 'code' in response_payload_map and 'message' in response_payload_map: - raise ShadowError('Request for shadow state returned error code {} with message "{}"'.format( - response_payload_map['code'], response_payload_map['message'] - )) - - return {'payload': payload} diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/Lambda.py b/examples/apps/greengrass-hello-world/greengrasssdk/Lambda.py deleted file mode 100755 index 9fdeaf0030..0000000000 --- a/examples/apps/greengrass-hello-world/greengrasssdk/Lambda.py +++ /dev/null @@ -1,139 +0,0 @@ -# -# Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - -import logging -import re - -from io import BytesIO - -from greengrass_common.function_arn_fields import FunctionArnFields -from greengrass_ipc_python_sdk.ipc_client import IPCClient, IPCException -from greengrasssdk.utils.testing import mock - -# Log messages in the SDK are part of customer's log because they're helpful for debugging -# customer's lambdas. Since we configured the root logger to log to customer's log and set the -# propagate flag of this logger to True. The log messages submitted from this logger will be -# sent to the customer's local Cloudwatch handler. -customer_logger = logging.getLogger(__name__) -customer_logger.propagate = True - -valid_base64_regex = '^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$' - - -class InvocationException(Exception): - pass - - -class Client: - def __init__(self, endpoint='localhost', port=8000): - """ - :param endpoint: Endpoint used to connect to IPC. - :type endpoint: str - - :param port: Port number used to connect to the :code:`endpoint`. - :type port: int - """ - self.ipc = IPCClient(endpoint=endpoint, port=port) - - def invoke(self, **kwargs): - - # FunctionName is a required parameter - if 'FunctionName' not in kwargs: - raise ValueError( - '"FunctionName" argument of Lambda.Client.invoke is a required argument but was not provided.' - ) - - arn_fields = FunctionArnFields(kwargs['FunctionName']) - arn_qualifier = arn_fields.qualifier - - # A Function qualifier can be provided as part of the ARN in FunctionName, or it can be provided here. The - # behavior of the cloud is to throw an exception if both are specified but not equal - extraneous_qualifier = kwargs.get('Qualifier', '') - - if extraneous_qualifier and arn_qualifier and arn_qualifier != extraneous_qualifier: - raise ValueError('The derived qualifier from the function name does not match the specified qualifier.') - - final_qualifier = arn_qualifier if arn_qualifier else extraneous_qualifier - - try: - # GGC v1.9.0 or newer - function_arn = FunctionArnFields.build_function_arn(arn_fields.unqualified_arn, final_qualifier) - except AttributeError: - # older GGC version - raise AttributeError('class FunctionArnFields has no attribute \'build_function_arn\'. build_function_arn ' - 'is introduced in GGC v1.9.0. Please check your GGC version.') - - # ClientContext must be base64 if given, but is an option parameter - try: - client_context = kwargs.get('ClientContext', b'').decode() - except AttributeError as e: - customer_logger.exception(e) - raise ValueError( - '"ClientContext" argument must be a byte string or support a decode method which returns a string' - ) - - if client_context: - if not re.match(valid_base64_regex, client_context): - raise ValueError('"ClientContext" argument of Lambda.Client.invoke must be base64 encoded.') - - # Payload is an optional parameter - payload = kwargs.get('Payload', b'') - invocation_type = kwargs.get('InvocationType', 'RequestResponse') - customer_logger.debug('Invoking local lambda "{}" with payload "{}" and client context "{}"'.format( - function_arn, payload, client_context)) - - # Post the work to IPC and return the result of that work - return self._invoke_internal(function_arn, payload, client_context, invocation_type) - - @mock - def _invoke_internal(self, function_arn, payload, client_context, invocation_type="RequestResponse"): - """ - This private method is seperate from the main, public invoke method so that other code within this SDK can - give this Lambda client a raw payload/client context to invoke with, rather than having it built for them. - This lets you include custom ExtensionMap_ values like subject which are needed for our internal pinned Lambdas. - """ - customer_logger.debug('Invoking Lambda function "{}" with Greengrass Message "{}"'.format(function_arn, payload)) - - try: - invocation_id = self.ipc.post_work(function_arn, payload, client_context, invocation_type) - - if invocation_type == "Event": - # TODO: Properly return errors based on BOTO response - # https://boto3.readthedocs.io/en/latest/reference/services/lambda.html#Lambda.Client.invoke - return {'Payload': b'', 'FunctionError': ''} - - work_result_output = self.ipc.get_work_result(function_arn, invocation_id) - if not work_result_output.func_err: - output_payload = StreamingBody(work_result_output.payload) - else: - output_payload = work_result_output.payload - invoke_output = { - 'Payload': output_payload, - 'FunctionError': work_result_output.func_err, - } - return invoke_output - except IPCException as e: - customer_logger.exception(e) - raise InvocationException('Failed to invoke function due to ' + str(e)) - - -class StreamingBody(object): - """Wrapper class for http response payload - - This provides a consistent interface to AWS Lambda Python SDK - """ - def __init__(self, payload): - self._raw_stream = BytesIO(payload) - self._amount_read = 0 - - def read(self, amt=None): - """Read at most amt bytes from the stream. - If the amt argument is omitted, read all data. - """ - chunk = self._raw_stream.read(amt) - self._amount_read += len(chunk) - return chunk - - def close(self): - self._raw_stream.close() diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/SecretsManager.py b/examples/apps/greengrass-hello-world/greengrasssdk/SecretsManager.py deleted file mode 100755 index 2a8385e256..0000000000 --- a/examples/apps/greengrass-hello-world/greengrasssdk/SecretsManager.py +++ /dev/null @@ -1,160 +0,0 @@ -# -# Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - -import json -import logging -from datetime import datetime -from decimal import Decimal - -from greengrasssdk import Lambda -from greengrass_common.env_vars import MY_FUNCTION_ARN, SECRETS_MANAGER_FUNCTION_ARN - -# Log messages in the SDK are part of customer's log because they're helpful for debugging -# customer's lambdas. Since we configured the root logger to log to customer's log and set the -# propagate flag of this logger to True. The log messages submitted from this logger will be -# sent to the customer's local Cloudwatch handler. -customer_logger = logging.getLogger(__name__) -customer_logger.propagate = True - -KEY_NAME_PAYLOAD = 'Payload' -KEY_NAME_STATUS = 'Status' -KEY_NAME_MESSAGE = 'Message' -KEY_NAME_SECRET_ID = 'SecretId' -KEY_NAME_VERSION_ID = 'VersionId' -KEY_NAME_VERSION_STAGE = 'VersionStage' -KEY_NAME_CREATED_DATE = "CreatedDate" - - -class SecretsManagerError(Exception): - pass - - -class Client: - def __init__(self): - self.lambda_client = Lambda.Client() - - def get_secret_value(self, **kwargs): - r""" - Call secrets manager lambda to obtain the requested secret value. - - :Keyword Arguments: - * *SecretId* (``string``) -- - [REQUIRED] - Specifies the secret containing the version that you want to retrieve. You can specify either the - Amazon Resource Name (ARN) or the friendly name of the secret. - * *VersionId* (``string``) -- - Specifies the unique identifier of the version of the secret that you want to retrieve. If you - specify this parameter then don't specify ``VersionStage`` . If you don't specify either a - ``VersionStage`` or ``SecretVersionId`` then the default is to perform the operation on the version - with the ``VersionStage`` value of ``AWSCURRENT`` . - - This value is typically a UUID-type value with 32 hexadecimal digits. - * *VersionStage* (``string``) -- - Specifies the secret version that you want to retrieve by the staging label attached to the - version. - - Staging labels are used to keep track of different versions during the rotation process. If you - use this parameter then don't specify ``SecretVersionId`` . If you don't specify either a - ``VersionStage`` or ``SecretVersionId`` , then the default is to perform the operation on the - version with the ``VersionStage`` value of ``AWSCURRENT`` . - - :returns: (``dict``) -- - * *ARN* (``string``) -- - The ARN of the secret. - * *Name* (``string``) -- - The friendly name of the secret. - * *VersionId* (``string``) -- - The unique identifier of this version of the secret. - * *SecretBinary* (``bytes``) -- - The decrypted part of the protected secret information that was originally provided as - binary data in the form of a byte array. The response parameter represents the binary data - as a base64-encoded string. - - This parameter is not used if the secret is created by the Secrets Manager console. - - If you store custom information in this field of the secret, then you must code your Lambda - rotation function to parse and interpret whatever you store in the ``SecretString`` or - ``SecretBinary`` fields. - * *SecretString* (``string``) -- - The decrypted part of the protected secret information that was originally provided as a - string. - - If you create this secret by using the Secrets Manager console then only the ``SecretString`` - parameter contains data. Secrets Manager stores the information as a JSON structure of - key/value pairs that the Lambda rotation function knows how to parse. - - If you store custom information in the secret by using the CreateSecret , UpdateSecret , or - PutSecretValue API operations instead of the Secrets Manager console, or by using the - *Other secret type* in the console, then you must code your Lambda rotation function to - parse and interpret those values. - * *VersionStages* (``list``) -- - A list of all of the staging labels currently attached to this version of the secret. - * (``string``) -- - * *CreatedDate* (``datetime``) -- - The date and time that this version of the secret was created. - """ - - secret_id = self._get_required_parameter(KEY_NAME_SECRET_ID, **kwargs) - version_id = kwargs.get(KEY_NAME_VERSION_ID, '') - version_stage = kwargs.get(KEY_NAME_VERSION_STAGE, '') - - if version_id: # TODO: Remove this once we support query by VersionId - raise SecretsManagerError('Query by VersionId is not yet supported') - if version_id and version_stage: - raise ValueError('VersionId and VersionStage cannot both be specified at the same time') - - request_payload_bytes = self._generate_request_payload_bytes(secret_id=secret_id, - version_id=version_id, - version_stage=version_stage) - - customer_logger.debug('Retrieving secret value with id "{}", version id "{}" version stage "{}"' - .format(secret_id, version_id, version_stage)) - response = self.lambda_client._invoke_internal( - SECRETS_MANAGER_FUNCTION_ARN, - request_payload_bytes, - b'', # We do not need client context for Secrets Manager back-end lambda - ) # Use Request/Response here as we are mimicking boto3 Http APIs for SecretsManagerService - - payload = response[KEY_NAME_PAYLOAD].read() - payload_dict = json.loads(payload.decode('utf-8')) - - # All customer facing errors are presented within the response payload. For example: - # { - # "code": 404, - # "message": "Resource not found" - # } - if KEY_NAME_STATUS in payload_dict and KEY_NAME_MESSAGE in payload_dict: - raise SecretsManagerError('Request for secret value returned error code {} with message {}'.format( - payload_dict[KEY_NAME_STATUS], payload_dict[KEY_NAME_MESSAGE] - )) - - # Time is serialized as epoch timestamp (int) upon IPC routing. We need to deserialize it back to datetime object in Python - payload_dict[KEY_NAME_CREATED_DATE] = datetime.fromtimestamp( - # Cloud response contains timestamp in milliseconds while datetime.fromtimestamp is expecting seconds - Decimal(payload_dict[KEY_NAME_CREATED_DATE]) / Decimal(1000) - ) - - return payload_dict - - def _generate_request_payload_bytes(self, secret_id, version_id, version_stage): - request_payload = { - KEY_NAME_SECRET_ID: secret_id, - } - if version_stage: - request_payload[KEY_NAME_VERSION_STAGE] = version_stage - - # TODO: Add VersionId once we support query by VersionId - - # The allowed chars for secret id and version stage are strictly enforced when customers are configuring them - # through Secrets Manager Service in the cloud: - # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_CreateSecret.html#API_CreateSecret_RequestSyntax - return json.dumps(request_payload).encode() - - @staticmethod - def _get_required_parameter(parameter_name, **kwargs): - if parameter_name not in kwargs: - raise ValueError('Parameter "{parameter_name}" is a required parameter but was not provided.'.format( - parameter_name=parameter_name - )) - return kwargs[parameter_name] diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/__init__.py b/examples/apps/greengrass-hello-world/greengrasssdk/__init__.py deleted file mode 100755 index 916d0dc264..0000000000 --- a/examples/apps/greengrass-hello-world/greengrasssdk/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright 2010-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - -from .client import client -from .Lambda import StreamingBody - -__version__ = '1.4.0' -INTERFACE_VERSION = '1.3' diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/client.py b/examples/apps/greengrass-hello-world/greengrasssdk/client.py deleted file mode 100755 index 53c92d0ff8..0000000000 --- a/examples/apps/greengrass-hello-world/greengrasssdk/client.py +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - - -def client(client_type, *args): - if client_type == 'lambda': - from .Lambda import Client - elif client_type == 'iot-data': - from .IoTDataPlane import Client - elif client_type == 'secretsmanager': - from .SecretsManager import Client - else: - raise Exception('Client type {} is not recognized.'.format(repr(client_type))) - - return Client(*args) diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/utils/__init__.py b/examples/apps/greengrass-hello-world/greengrasssdk/utils/__init__.py deleted file mode 100755 index e69de29bb2..0000000000 diff --git a/examples/apps/greengrass-hello-world/greengrasssdk/utils/testing.py b/examples/apps/greengrass-hello-world/greengrasssdk/utils/testing.py deleted file mode 100755 index 0a0bbf8ec7..0000000000 --- a/examples/apps/greengrass-hello-world/greengrasssdk/utils/testing.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. -# - -import json -from functools import wraps -from greengrass_common.env_vars import MY_FUNCTION_ARN - - -def mock(func): - """ - mock decorates _invoke_internal by checking if MY_FUNCTION_ARN is present - if MY_FUNCTION_ARN is present, the actual _invoke_internal is invoked - otherwise, the mock _invoke_internal is invoked - """ - @wraps(func) - def mock_invoke_internal(self, function_arn, payload, client_context, invocation_type="RequestResponse"): - if MY_FUNCTION_ARN is None: - if invocation_type == 'RequestResponse': - return { - 'Payload': json.dumps({ - 'TestKey': 'TestValue' - }), - 'FunctionError': '' - } - elif invocation_type == 'Event': - return { - 'Payload': b'', - 'FunctionError': '' - } - else: - raise Exception('Unsupported invocation type {}'.format(invocation_type)) - else: - return func(self, function_arn, payload, client_context, invocation_type) - return mock_invoke_internal diff --git a/examples/apps/greengrass-hello-world/license/license.txt b/examples/apps/greengrass-hello-world/license/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/greengrass-hello-world/license/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/greengrass-hello-world/template.yaml b/examples/apps/greengrass-hello-world/template.yaml deleted file mode 100644 index e91a69e741..0000000000 --- a/examples/apps/greengrass-hello-world/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Deploy this lambda to a Greengrass core where it will send a hello world message to a topic -Parameters: - IdentityNameParameter: - Type: String -Resources: - greengrasshelloworld: - Type: 'AWS::Serverless::Function' - Properties: - Handler: greengrassHelloWorld.function_handler - Runtime: python3.7 - CodeUri: . - Description: >- - Deploy this lambda to a Greengrass core where it will send a hello world message to a topic - MemorySize: 128 - Timeout: 3 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter diff --git a/examples/apps/hello-world-python/lambda_function.py b/examples/apps/hello-world-python/lambda_function.py deleted file mode 100644 index 15e8e300e4..0000000000 --- a/examples/apps/hello-world-python/lambda_function.py +++ /dev/null @@ -1,14 +0,0 @@ -from __future__ import print_function - -import json - -print('Loading function') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - print("value1 = " + event['key1']) - print("value2 = " + event['key2']) - print("value3 = " + event['key3']) - return event['key1'] # Echo back the first key value - #raise Exception('Something went wrong') diff --git a/examples/apps/hello-world-python/license.txt b/examples/apps/hello-world-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/hello-world-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/hello-world-python/readme b/examples/apps/hello-world-python/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/hello-world-python/template.yaml b/examples/apps/hello-world-python/template.yaml deleted file mode 100644 index e0c0e1af83..0000000000 --- a/examples/apps/hello-world-python/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: A starter AWS Lambda function. -Parameters: - IdentityNameParameter: - Type: String -Resources: - helloworldpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: A starter AWS Lambda function. - MemorySize: 128 - Timeout: 3 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter diff --git a/examples/apps/hello-world-python3/lambda_function.py b/examples/apps/hello-world-python3/lambda_function.py deleted file mode 100644 index 7a90653e29..0000000000 --- a/examples/apps/hello-world-python3/lambda_function.py +++ /dev/null @@ -1,12 +0,0 @@ -import json - -print('Loading function') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - print("value1 = " + event['key1']) - print("value2 = " + event['key2']) - print("value3 = " + event['key3']) - return event['key1'] # Echo back the first key value - #raise Exception('Something went wrong') diff --git a/examples/apps/hello-world-python3/license.txt b/examples/apps/hello-world-python3/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/hello-world-python3/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/hello-world-python3/readme b/examples/apps/hello-world-python3/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/hello-world-python3/template.yaml b/examples/apps/hello-world-python3/template.yaml deleted file mode 100644 index d23e9027a4..0000000000 --- a/examples/apps/hello-world-python3/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: A starter AWS Lambda function. -Parameters: - IdentityNameParameter: - Type: String -Resources: - helloworldpython3: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python3.6 - CodeUri: . - Description: A starter AWS Lambda function. - MemorySize: 128 - Timeout: 3 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter diff --git a/examples/apps/hello-world/index.js b/examples/apps/hello-world/index.js deleted file mode 100644 index b92b0e8f41..0000000000 --- a/examples/apps/hello-world/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - console.log('value1 =', event.key1); - console.log('value2 =', event.key2); - console.log('value3 =', event.key3); - callback(null, event.key1); // Echo back the first key value - //callback('Something went wrong'); -}; diff --git a/examples/apps/hello-world/license.txt b/examples/apps/hello-world/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/hello-world/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/hello-world/readme b/examples/apps/hello-world/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/hello-world/template.yaml b/examples/apps/hello-world/template.yaml deleted file mode 100644 index 7e79099d93..0000000000 --- a/examples/apps/hello-world/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: A starter AWS Lambda function. -Parameters: - IdentityNameParameter: - Type: String -Resources: - helloworld: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: A starter AWS Lambda function. - MemorySize: 128 - Timeout: 3 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter \ No newline at end of file diff --git a/examples/apps/hello-world/testEvent.json b/examples/apps/hello-world/testEvent.json deleted file mode 100644 index fd2722e859..0000000000 --- a/examples/apps/hello-world/testEvent.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "key1": "value1", - "key2": "value2", - "key3": "value3" -} diff --git a/examples/apps/https-request/index.js b/examples/apps/https-request/index.js deleted file mode 100644 index 50a5d1496f..0000000000 --- a/examples/apps/https-request/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const https = require('https'); - -/** - * Pass the data to send as `event.data`, and the request options as - * `event.options`. For more information see the HTTPS module documentation - * at https://nodejs.org/api/https.html. - * - * Will succeed with the response body. - */ -exports.handler = (event, context, callback) => { - const req = https.request(event.options, (res) => { - let body = ''; - console.log('Status:', res.statusCode); - console.log('Headers:', JSON.stringify(res.headers)); - res.setEncoding('utf8'); - res.on('data', (chunk) => body += chunk); - res.on('end', () => { - console.log('Successfully processed HTTPS response'); - // If we know it's JSON, parse it - if (res.headers['content-type'] === 'application/json') { - body = JSON.parse(body); - } - callback(null, body); - }); - }); - req.on('error', callback); - req.write(JSON.stringify(event.data)); - req.end(); -}; diff --git a/examples/apps/https-request/license.txt b/examples/apps/https-request/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/https-request/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/https-request/readme b/examples/apps/https-request/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/https-request/template.yaml b/examples/apps/https-request/template.yaml deleted file mode 100644 index 98e3181f10..0000000000 --- a/examples/apps/https-request/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrates using a built-in Node.js module to make an HTTPS request. -Parameters: - IdentityNameParameter: - Type: String -Resources: - httpsrequest: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Demonstrates using a built-in Node.js module to make an HTTPS request. - MemorySize: 128 - Timeout: 60 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter diff --git a/examples/apps/image-processing-service/index.js b/examples/apps/image-processing-service/index.js deleted file mode 100644 index b3f340d80f..0000000000 --- a/examples/apps/image-processing-service/index.js +++ /dev/null @@ -1,141 +0,0 @@ -'use strict'; - -const im = require('imagemagick'); -const fs = require('fs'); - - -const postProcessResource = (resource, fn) => { - let ret = null; - if (resource) { - if (fn) { - ret = fn(resource); - } - try { - fs.unlinkSync(resource); - } catch (err) { - // Ignore - } - } - return ret; -}; - - -const identify = (req, callback) => { - if (!req.base64Image) { - const msg = 'Invalid identify request: no "base64Image" field supplied'; - console.log(msg); - return callback(msg); - } - const tmpFile = `/tmp/inputFile.${(req.inputExtension || 'png')}`; - const buffer = new Buffer(req.base64Image, 'base64'); - fs.writeFileSync(tmpFile, buffer); - const args = req.customArgs ? req.customArgs.concat([tmpFile]) : tmpFile; - im.identify(args, (err, output) => { - fs.unlinkSync(tmpFile); - if (err) { - console.log('Identify operation failed:', err); - callback(err); - } else { - console.log('Identify operation completed successfully'); - callback(null, output); - } - }); -}; - -const resize = (req, callback) => { - const resizeReq = req; - if (!resizeReq.base64Image) { - const msg = 'Invalid resize request: no "base64Image" field supplied'; - console.log(msg); - return callback(msg); - } - // If neither height nor width was provided, turn this into a thumbnailing request - if (!resizeReq.height && !resizeReq.width) { - resizeReq.width = 100; - } - const resizedFile = `/tmp/resized.${(resizeReq.outputExtension || 'png')}`; - const buffer = new Buffer(resizeReq.base64Image, 'base64'); - delete resizeReq.base64Image; - delete resizeReq.outputExtension; - resizeReq.srcData = buffer; - resizeReq.dstPath = resizedFile; - try { - im.resize(resizeReq, (err) => { - if (err) { - throw err; - } else { - console.log('Resize operation completed successfully'); - callback(null, postProcessResource(resizedFile, (file) => new Buffer(fs.readFileSync(file)).toString('base64'))); - } - }); - } catch (err) { - console.log('Resize operation failed:', err); - callback(err); - } -}; - -const convert = (req, callback) => { - const customArgs = req.customArgs || []; - let inputFile = null; - let outputFile = null; - if (req.base64Image) { - inputFile = `/tmp/inputFile.${(req.inputExtension || 'png')}`; - const buffer = new Buffer(req.base64Image, 'base64'); - fs.writeFileSync(inputFile, buffer); - customArgs.unshift(inputFile); - } - if (req.outputExtension) { - outputFile = `/tmp/outputFile.${req.outputExtension}`; - customArgs.push(outputFile); - } - im.convert(customArgs, (err, output) => { - if (err) { - console.log('Convert operation failed:', err); - callback(err); - } else { - console.log('Convert operation completed successfully'); - postProcessResource(inputFile); - if (outputFile) { - callback(null, postProcessResource(outputFile, (file) => new Buffer(fs.readFileSync(file)).toString('base64'))); - } else { - // Return the command line output as a debugging aid - callback(null, output); - } - } - }); -}; - - -exports.handler = (event, context, callback) => { - const req = event; - const operation = req.operation; - delete req.operation; - if (operation) { - console.log(`Operation ${operation} 'requested`); - } - - switch (operation) { - case 'ping': - callback(null, 'pong'); - break; - case 'getDimensions': - req.customArgs = ['-format', '%wx%h']; - /* falls through */ - case 'identify': - identify(req, callback); - break; - case 'thumbnail': // Synonym for resize - case 'resize': - resize(req, callback); - break; - case 'getSample': - req.customArgs = ['rose:']; - req.outputExtension = req.outputExtension || 'png'; - /* falls through */ - case 'convert': - convert(req, callback); - break; - default: - callback(new Error(`Unrecognized operation "${operation}"`)); - } -}; diff --git a/examples/apps/image-processing-service/license.txt b/examples/apps/image-processing-service/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/image-processing-service/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/image-processing-service/readme b/examples/apps/image-processing-service/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/image-processing-service/template.yaml b/examples/apps/image-processing-service/template.yaml deleted file mode 100644 index 15b640e2ae..0000000000 --- a/examples/apps/image-processing-service/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Uses ImageMagick to perform simple image processing operations, such as resizing. -Parameters: - IdentityNameParameter: - Type: String -Resources: - imageprocessingservice: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Uses ImageMagick to perform simple image processing operations, such as resizing. - MemorySize: 512 - Timeout: 30 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter diff --git a/examples/apps/inbound-ses-spam-filter-python/lambda_function.py b/examples/apps/inbound-ses-spam-filter-python/lambda_function.py deleted file mode 100644 index ad5aaaabba..0000000000 --- a/examples/apps/inbound-ses-spam-filter-python/lambda_function.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import print_function - -import boto3 -import json -import os - -from datetime import datetime - -# Update the emailDomain environment variable to the correct domain, e.g. .com -EMAIL_DOMAIN = os.environ['emailDomain'] - - -def print_with_timestamp(*args): - print(datetime.utcnow().isoformat(), *args) - - -def lambda_handler(event, context): - print_with_timestamp('Starting - inbound-ses-spam-filter') - - ses_notification = event['Records'][0]['ses'] - message_id = ses_notification['mail']['messageId'] - receipt = ses_notification['receipt'] - - print_with_timestamp('Processing message:', message_id) - - # Check if any spam check failed - if (receipt['spfVerdict']['status'] == 'FAIL' or - receipt['dkimVerdict']['status'] == 'FAIL' or - receipt['spamVerdict']['status'] == 'FAIL' or - receipt['virusVerdict']['status'] == 'FAIL'): - - send_bounce_params = { - 'OriginalMessageId': message_id, - 'BounceSender': 'mailer-daemon@{}'.format(EMAIL_DOMAIN), - 'MessageDsn': { - 'ReportingMta': 'dns; {}'.format(EMAIL_DOMAIN), - 'ArrivalDate': datetime.now().isoformat() - }, - 'BouncedRecipientInfoList': [] - } - - for recipient in receipt['recipients']: - send_bounce_params['BouncedRecipientInfoList'].append({ - 'Recipient': recipient, - 'BounceType': 'ContentRejected' - }) - - print_with_timestamp('Bouncing message with parameters:') - print_with_timestamp(json.dumps(send_bounce_params)) - - try: - ses_client = boto3.client('ses') - bounceResponse = ses_client.send_bounce(**send_bounce_params) - print_with_timestamp('Bounce for message ', message_id, ' sent, bounce message ID: ', bounceResponse['MessageId']) - return {'disposition': 'stop_rule_set'} - except Exception as e: - print_with_timestamp(e) - print_with_timestamp('An error occurred while sending bounce for message: ', message_id) - raise e - else: - print_with_timestamp('Accepting message:', message_id) diff --git a/examples/apps/inbound-ses-spam-filter-python/license.txt b/examples/apps/inbound-ses-spam-filter-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/inbound-ses-spam-filter-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/inbound-ses-spam-filter-python/readme b/examples/apps/inbound-ses-spam-filter-python/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/inbound-ses-spam-filter-python/requirements.txt b/examples/apps/inbound-ses-spam-filter-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/inbound-ses-spam-filter-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/inbound-ses-spam-filter-python/template.yaml b/examples/apps/inbound-ses-spam-filter-python/template.yaml deleted file mode 100644 index f61ec24fa9..0000000000 --- a/examples/apps/inbound-ses-spam-filter-python/template.yaml +++ /dev/null @@ -1,24 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A simple email filter for protection against spam and viruses as well as DKIM and SPF failures. -Parameters: - IdentityNameParameter: - Type: String -Resources: - inboundsesspamfilterpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - A simple email filter for protection against spam and viruses as well as DKIM and SPF failures. - MemorySize: 128 - Timeout: 10 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter - Environment: - Variables: - emailDomain: diff --git a/examples/apps/inbound-ses-spam-filter/index.js b/examples/apps/inbound-ses-spam-filter/index.js deleted file mode 100644 index c029cb34c8..0000000000 --- a/examples/apps/inbound-ses-spam-filter/index.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; - -const AWS = require('aws-sdk'); - -// Update the emailDomain environment variable to the correct domain, e.g. .com -const emailDomain = process.env.emailDomain; - -exports.handler = (event, context, callback) => { - console.log('Spam filter starting'); - - const sesNotification = event.Records[0].ses; - const messageId = sesNotification.mail.messageId; - const receipt = sesNotification.receipt; - - console.log('Processing message:', messageId); - - // Check if any spam check failed - if (receipt.spfVerdict.status === 'FAIL' || - receipt.dkimVerdict.status === 'FAIL' || - receipt.spamVerdict.status === 'FAIL' || - receipt.virusVerdict.status === 'FAIL') { - const sendBounceParams = { - BounceSender: `mailer-daemon@${emailDomain}`, - OriginalMessageId: messageId, - MessageDsn: { - ReportingMta: `dns; ${emailDomain}`, - ArrivalDate: new Date(), - ExtensionFields: [], - }, - BouncedRecipientInfoList: receipt.recipients.map((recipient) => ({ - Recipient: recipient, - BounceType: 'ContentRejected', - })), - }; - - console.log('Bouncing message with parameters:'); - console.log(JSON.stringify(sendBounceParams, null, 2)); - - new AWS.SES().sendBounce(sendBounceParams, (err, data) => { - if (err) { - console.log(`An error occurred while sending bounce for message: ${messageId}`, err); - callback(err); - } else { - console.log(`Bounce for message ${messageId} sent, bounce message ID: ${data.MessageId}`); - callback(null, { - disposition: 'stop_rule_set', - }); - } - }); - } else { - console.log('Accepting message:', messageId); - callback(); - } -}; diff --git a/examples/apps/inbound-ses-spam-filter/license.txt b/examples/apps/inbound-ses-spam-filter/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/inbound-ses-spam-filter/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/inbound-ses-spam-filter/readme b/examples/apps/inbound-ses-spam-filter/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/inbound-ses-spam-filter/template.yaml b/examples/apps/inbound-ses-spam-filter/template.yaml deleted file mode 100644 index f947d6280a..0000000000 --- a/examples/apps/inbound-ses-spam-filter/template.yaml +++ /dev/null @@ -1,28 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A simple email filter for protection against spam and viruses as well as DKIM and SPF failures. -Parameters: - IdentityNameParameter: - Type: String -Outputs: - InboundSESSpamFilterFunction: - Description: "inboundsesspamfilter Lambda Function ARN" - Value: !GetAtt inboundsesspamfilter.Arn -Resources: - inboundsesspamfilter: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - A simple email filter for protection against spam and viruses as well as DKIM and SPF failures. - MemorySize: 128 - Timeout: 10 - Policies: - - SESSendBouncePolicy: - IdentityName: !Ref IdentityNameParameter - Environment: - Variables: - emailDomain: diff --git a/examples/apps/inspector-scheduled-run/index.js b/examples/apps/inspector-scheduled-run/index.js deleted file mode 100644 index 3a888712cb..0000000000 --- a/examples/apps/inspector-scheduled-run/index.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -/** - * A blueprint to schedule a recurring assessment run for an Amazon Inspector assessment template. - * - * This blueprint assumes that you've already done the following: - * 1. onboarded with the Amazon Inspector service https://aws.amazon.com/inspector - * 2. created an assessment target - what hosts you want to assess - * 3. created an assessment template - how you want to assess your target - * - * Then, all you need to do to use this blueprint is to define an environment variable in the Lambda console called - * `assessmentTemplateArn` and provide the template arn you want to run on a schedule. - */ - -const AWS = require('aws-sdk'); - -const inspector = new AWS.Inspector(); - -const params = { - assessmentTemplateArn: process.env.assessmentTemplateArn, -}; - -exports.handler = (event, context, callback) => { - try { - // Inspector.StartAssessmentRun response will look something like: - // {"assessmentRunArn":"arn:aws:inspector:us-west-2:123456789012:target/0-wJ0KWygn/template/0-jRPJqnQh/run/0-Ga1lDjhP" - inspector.startAssessmentRun(params, (error, data) => { - if (error) { - console.log(error, error.stack); - return callback(error); - } - - console.log(data); - return callback(null, data); - }); - } catch (error) { - console.log('Caught Error: ', error); - callback(error); - } -}; diff --git a/examples/apps/inspector-scheduled-run/license.txt b/examples/apps/inspector-scheduled-run/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/inspector-scheduled-run/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/inspector-scheduled-run/readme b/examples/apps/inspector-scheduled-run/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/inspector-scheduled-run/template.yaml b/examples/apps/inspector-scheduled-run/template.yaml deleted file mode 100644 index 7906bfc686..0000000000 --- a/examples/apps/inspector-scheduled-run/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Schedules a recurring Amazon Inspector assessment run -Parameters: - TopicNameParameter: - Type: String -Resources: - inspectorscheduledrun: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Schedules a recurring Amazon Inspector assessment run - MemorySize: 128 - Timeout: 10 - Policies: - - SNSCrudPolicy: - TopicName: !Ref TopicNameParameter - Environment: - Variables: - assessmentTemplateArn: diff --git a/examples/apps/kinesis-analytics-process-compressed-record/index.js b/examples/apps/kinesis-analytics-process-compressed-record/index.js deleted file mode 100644 index fcbd3e955b..0000000000 --- a/examples/apps/kinesis-analytics-process-compressed-record/index.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; -console.log('Loading function'); -const zlib = require('zlib'); - -exports.handler = (event, context, callback) => { - let success = 0; // Number of valid entries found - let failure = 0; // Number of invalid entries found - /* Process the list of records */ - const output = event.records.map((record) => { - /* Data is base64 encoded, so decode here */ - const compressedData = Buffer.from(record.data, 'base64'); - try { - const decompressedData = zlib.unzipSync(compressedData); - /* Encode decompressed JSON or CSV */ - const result = (Buffer.from(decompressedData, 'utf8')).toString('base64'); - success++; - return { - recordId: record.recordId, - result: 'Ok', - data: result, - }; - } catch (err) { - failure++; - return { - recordId: record.recordId, - result: 'ProcessingFailed', - data: record.data, - }; - } - }); - console.log(`Processing completed. Successful records ${success}, Failed records ${failure}.`); - callback(null, { - records: output, - }); -}; diff --git a/examples/apps/kinesis-analytics-process-compressed-record/license.txt b/examples/apps/kinesis-analytics-process-compressed-record/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-analytics-process-compressed-record/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-compressed-record/readme b/examples/apps/kinesis-analytics-process-compressed-record/readme deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/apps/kinesis-analytics-process-compressed-record/template.yaml b/examples/apps/kinesis-analytics-process-compressed-record/template.yaml deleted file mode 100644 index 3b784ed9dc..0000000000 --- a/examples/apps/kinesis-analytics-process-compressed-record/template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Analytics record pre-processor that receives compressed - (GZIP or Deflate compressed) JSON or CSV records as input and returns - decompressed records with a processing status. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisanalyticsprocesscompressedrecord: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Analytics record pre-processor that receives - compressed (GZIP or Deflate compressed) JSON or CSV records as input and - returns decompressed records with a processing status. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter diff --git a/examples/apps/kinesis-analytics-process-compressed-record/testEvent.json b/examples/apps/kinesis-analytics-process-compressed-record/testEvent.json deleted file mode 100644 index 835449a4cf..0000000000 --- a/examples/apps/kinesis-analytics-process-compressed-record/testEvent.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "invocationId": "invocationIdExample", - "applicationArn": "arn:aws:kinesisanalytics:us-east-1:123456789012:application/example-application", - "streamArn": "arn:aws:kinesis:us-east-1:123456789012:stream/example-stream", - "records": [ - { - "recordId": "49571347871967966406409637155186850213682522142927749122", - "data": "H4sIAAAAAAAA/6vmUspLzE1VslLKTsxNzFHS4VJKTEkpSi0uBgol5SRmKHHVAgDd1tysJAAAAA==" - } - ] -} diff --git a/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/__init__.py b/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/__init__.py deleted file mode 100644 index 7812787320..0000000000 --- a/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#Kinesis Aggregation/Deaggregation Libraries for Python -# -#Copyright 2014, Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -#Licensed under the Amazon Software License (the "License"). -#You may not use this file except in compliance with the License. -#A copy of the License is located at -# -# http://aws.amazon.com/asl/ -# -#or in the "license" file accompanying this file. This file is distributed -#on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -#express or implied. See the License for the specific language governing -#permissions and limitations under the License. - -import md5 - -#Message aggregation protocol-specific constants -#(https://github.com/awslabs/amazon-kinesis-producer/blob/master/aggregation-format.md) -MAGIC = '\xf3\x89\x9a\xc2' -DIGEST_SIZE = md5.digest_size - -#Kinesis Limits -#(https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html) -MAX_BYTES_PER_RECORD = 1024*1024 # 1 MB diff --git a/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/deaggregator.py b/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/deaggregator.py deleted file mode 100644 index bdb3c6e8ea..0000000000 --- a/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/deaggregator.py +++ /dev/null @@ -1,72 +0,0 @@ -#Kinesis Aggregation/Deaggregation Libraries for Python -# -#Copyright 2014, Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -#Licensed under the Amazon Software License (the "License"). -#You may not use this file except in compliance with the License. -#A copy of the License is located at -# -# http://aws.amazon.com/asl/ -# -#or in the "license" file accompanying this file. This file is distributed -#on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -#express or implied. See the License for the specific language governing -#permissions and limitations under the License. - -from __future__ import print_function - -import aws_kinesis_agg -import base64 -import collections -import kpl_pb2 -import md5 -import StringIO -import sys - -def deaggregate_record(decoded_data): - '''Given a Kinesis record data that is decoded, deaggregate if it was packed using the - Kinesis Producer Library into individual records. This method will be a no-op for any - records that are not aggregated (but will still return them). - - decoded_data - the base64 decoded data that comprises either the KPL aggregated data, or the Kinesis payload directly. - return value - A list of deaggregated Kinesis record payloads (if the data is not aggregated, we just return a list with the payload alone) - ''' - - is_aggregated = True - - #Verify the magic header - data_magic = None - if(len(decoded_data) >= len(aws_kinesis_agg.MAGIC)): - data_magic = decoded_data[:len(aws_kinesis_agg.MAGIC)] - else: - print("Not aggregated") - is_aggregated = False - - decoded_data_no_magic = decoded_data[len(aws_kinesis_agg.MAGIC):] - - if aws_kinesis_agg.MAGIC != data_magic or len(decoded_data_no_magic) <= aws_kinesis_agg.DIGEST_SIZE: - is_aggregated = False - - if is_aggregated: - - #verify the MD5 digest - message_digest = decoded_data_no_magic[-aws_kinesis_agg.DIGEST_SIZE:] - message_data = decoded_data_no_magic[:-aws_kinesis_agg.DIGEST_SIZE] - - md5_calc = md5.new() - md5_calc.update(message_data) - calculated_digest = md5_calc.digest() - - if message_digest != calculated_digest: - return [decoded_data] - else: - #Extract the protobuf message - try: - ar = kpl_pb2.AggregatedRecord() - ar.ParseFromString(message_data) - - return [mr.data for mr in ar.records] - except BaseException as e: - raise e - else: - return [decoded_data] diff --git a/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/kpl_pb2.py b/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/kpl_pb2.py deleted file mode 100644 index 96cbe0adf8..0000000000 --- a/examples/apps/kinesis-analytics-process-kpl-record/aws_kinesis_agg/kpl_pb2.py +++ /dev/null @@ -1,202 +0,0 @@ -#Kinesis Aggregation/Deaggregation Libraries for Python -# -#Copyright 2014, Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -#Licensed under the Amazon Software License (the "License"). -#You may not use this file except in compliance with the License. -#A copy of the License is located at -# -# http://aws.amazon.com/asl/ -# -#or in the "license" file accompanying this file. This file is distributed -#on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either -#express or implied. See the License for the specific language governing -#permissions and limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: kpl.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='kpl.proto', - package='', - serialized_pb=_b('\n\tkpl.proto\"j\n\x10\x41ggregatedRecord\x12\x1b\n\x13partition_key_table\x18\x01 \x03(\t\x12\x1f\n\x17\x65xplicit_hash_key_table\x18\x02 \x03(\t\x12\x18\n\x07records\x18\x03 \x03(\x0b\x32\x07.Record\"!\n\x03Tag\x12\x0b\n\x03key\x18\x01 \x02(\t\x12\r\n\x05value\x18\x02 \x01(\t\"h\n\x06Record\x12\x1b\n\x13partition_key_index\x18\x01 \x02(\x04\x12\x1f\n\x17\x65xplicit_hash_key_index\x18\x02 \x01(\x04\x12\x0c\n\x04\x64\x61ta\x18\x03 \x02(\x0c\x12\x12\n\x04tags\x18\x04 \x03(\x0b\x32\x04.Tag') -) -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - - -_AGGREGATEDRECORD = _descriptor.Descriptor( - name='AggregatedRecord', - full_name='AggregatedRecord', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='partition_key_table', full_name='AggregatedRecord.partition_key_table', index=0, - number=1, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='explicit_hash_key_table', full_name='AggregatedRecord.explicit_hash_key_table', index=1, - number=2, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='records', full_name='AggregatedRecord.records', index=2, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=13, - serialized_end=119, -) - - -_TAG = _descriptor.Descriptor( - name='Tag', - full_name='Tag', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='key', full_name='Tag.key', index=0, - number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='value', full_name='Tag.value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=121, - serialized_end=154, -) - - -_RECORD = _descriptor.Descriptor( - name='Record', - full_name='Record', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='partition_key_index', full_name='Record.partition_key_index', index=0, - number=1, type=4, cpp_type=4, label=2, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='explicit_hash_key_index', full_name='Record.explicit_hash_key_index', index=1, - number=2, type=4, cpp_type=4, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='data', full_name='Record.data', index=2, - number=3, type=12, cpp_type=9, label=2, - has_default_value=False, default_value=_b(""), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='tags', full_name='Record.tags', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - serialized_start=156, - serialized_end=260, -) - -_AGGREGATEDRECORD.fields_by_name['records'].message_type = _RECORD -_RECORD.fields_by_name['tags'].message_type = _TAG -DESCRIPTOR.message_types_by_name['AggregatedRecord'] = _AGGREGATEDRECORD -DESCRIPTOR.message_types_by_name['Tag'] = _TAG -DESCRIPTOR.message_types_by_name['Record'] = _RECORD - -AggregatedRecord = _reflection.GeneratedProtocolMessageType('AggregatedRecord', (_message.Message,), dict( - DESCRIPTOR = _AGGREGATEDRECORD, - __module__ = 'kpl_pb2' - # @@protoc_insertion_point(class_scope:AggregatedRecord) - )) -_sym_db.RegisterMessage(AggregatedRecord) - -Tag = _reflection.GeneratedProtocolMessageType('Tag', (_message.Message,), dict( - DESCRIPTOR = _TAG, - __module__ = 'kpl_pb2' - # @@protoc_insertion_point(class_scope:Tag) - )) -_sym_db.RegisterMessage(Tag) - -Record = _reflection.GeneratedProtocolMessageType('Record', (_message.Message,), dict( - DESCRIPTOR = _RECORD, - __module__ = 'kpl_pb2' - # @@protoc_insertion_point(class_scope:Record) - )) -_sym_db.RegisterMessage(Record) - - -# @@protoc_insertion_point(module_scope) diff --git a/examples/apps/kinesis-analytics-process-kpl-record/lambda_function.py b/examples/apps/kinesis-analytics-process-kpl-record/lambda_function.py deleted file mode 100644 index ad5e2987c4..0000000000 --- a/examples/apps/kinesis-analytics-process-kpl-record/lambda_function.py +++ /dev/null @@ -1,35 +0,0 @@ -from __future__ import print_function - -from aws_kinesis_agg.deaggregator import deaggregate_record -import base64 - - -def construct_response_record(record_id, data, is_parse_success): - return { - 'recordId': record_id, - 'result': 'Ok' if is_parse_success else 'ProcessingFailed', - 'data': base64.b64encode(data)} - - -def process_kpl_record(kpl_record): - raw_kpl_record_data = base64.b64decode(kpl_record['data']) - try: - # Concatenate the data from de-aggregated records into a single output payload. - output_data = "".join(deaggregate_record(raw_kpl_record_data)) - return construct_response_record(kpl_record['recordId'], output_data, True) - except BaseException as e: - print('Processing failed with exception:' + str(e)) - return construct_response_record(kpl_record['recordId'], raw_kpl_record_data, False) - - -def lambda_handler(event, context): - '''A Python AWS Lambda function to process aggregated records sent to KinesisAnalytics.''' - raw_kpl_records = event['records'] - output = [process_kpl_record(kpl_record) for kpl_record in raw_kpl_records] - - # Print number of successful and failed records. - success_count = sum(1 for record in output if record['result'] == 'Ok') - failure_count = sum(1 for record in output if record['result'] == 'ProcessingFailed') - print('Processing completed. Successful records: {0}, Failed records: {1}.'.format(success_count, failure_count)) - - return {'records': output} diff --git a/examples/apps/kinesis-analytics-process-kpl-record/requirements.txt b/examples/apps/kinesis-analytics-process-kpl-record/requirements.txt deleted file mode 100644 index 8f390712e2..0000000000 --- a/examples/apps/kinesis-analytics-process-kpl-record/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -protobuf==3.5.1 diff --git a/examples/apps/kinesis-analytics-process-kpl-record/template.yaml b/examples/apps/kinesis-analytics-process-kpl-record/template.yaml deleted file mode 100644 index c72c4b4894..0000000000 --- a/examples/apps/kinesis-analytics-process-kpl-record/template.yaml +++ /dev/null @@ -1,30 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Analytics record pre-processor that receives Kinesis - Producer Library (KPL) aggregates of JSON or CSV records as input and returns - de-aggregated records with a processing status. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisanalyticsprocesskplrecord: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Analytics record pre-processor that receives Kinesis - Producer Library (KPL) aggregates of JSON or CSV records as input and - returns de-aggregated records with a processing status. - MemorySize: 128 - Timeout: 3 - Policies: - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter diff --git a/examples/apps/kinesis-analytics-process-record-python/lambda_function.py b/examples/apps/kinesis-analytics-process-record-python/lambda_function.py deleted file mode 100644 index 1797b7a18d..0000000000 --- a/examples/apps/kinesis-analytics-process-record-python/lambda_function.py +++ /dev/null @@ -1,24 +0,0 @@ -from __future__ import print_function - -import base64 - -print('Loading function') - - -def lambda_handler(event, context): - output = [] - - for record in event['records']: - payload = base64.b64decode(record['data']) - - # Do custom processing on the record payload here - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(payload) - } - output.append(output_record) - - print('Successfully processed {} records.'.format(len(event['records']))) - - return {'records': output} diff --git a/examples/apps/kinesis-analytics-process-record-python/license.txt b/examples/apps/kinesis-analytics-process-record-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-analytics-process-record-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-record-python/readme b/examples/apps/kinesis-analytics-process-record-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-analytics-process-record-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-record-python/requirements.txt b/examples/apps/kinesis-analytics-process-record-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-analytics-process-record-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-analytics-process-record-python/template.yaml b/examples/apps/kinesis-analytics-process-record-python/template.yaml deleted file mode 100644 index 0b37e10659..0000000000 --- a/examples/apps/kinesis-analytics-process-record-python/template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Analytics record pre-processor that receives JSON or CSV - records as input and returns them with a processing status. Use this processor - as a starting point for custom transformation logic. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisanalyticsprocessrecordpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Analytics record pre-processor that receives JSON or - CSV records as input and returns them with a processing status. Use this - processor as a starting point for custom transformation logic. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-record/index.js b/examples/apps/kinesis-analytics-process-record/index.js deleted file mode 100644 index 6a9cd60644..0000000000 --- a/examples/apps/kinesis-analytics-process-record/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - /* Process the list of records */ - const output = event.records.map((record) => ({ - recordId: record.recordId, - result: 'Ok', - data: record.data, - })); - console.log(`Processing completed. Successful records ${output.length}.`); - callback(null, { records: output }); -}; diff --git a/examples/apps/kinesis-analytics-process-record/license.txt b/examples/apps/kinesis-analytics-process-record/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-analytics-process-record/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-record/readme b/examples/apps/kinesis-analytics-process-record/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-analytics-process-record/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-record/template.yaml b/examples/apps/kinesis-analytics-process-record/template.yaml deleted file mode 100644 index f31ed620f9..0000000000 --- a/examples/apps/kinesis-analytics-process-record/template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Analytics record pre-processor that receives JSON or CSV - records as input and returns them with a processing status. Use this processor - as a starting point for custom transformation logic. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisanalyticsprocessrecord: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Analytics record pre-processor that receives JSON or - CSV records as input and returns them with a processing status. Use this - processor as a starting point for custom transformation logic. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-analytics-process-record/testEvent.json b/examples/apps/kinesis-analytics-process-record/testEvent.json deleted file mode 100644 index bb7fbd446e..0000000000 --- a/examples/apps/kinesis-analytics-process-record/testEvent.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "invocationId": "invocationIdExample", - "applicationArn": "arn:aws:kinesisanalytics:us-east-1:123456789012:application/example-application", - "streamArn": "arn:aws:kinesis:us-east-1:123456789012:stream/example-stream", - "records": [ - { - "recordId": "49571347871967966406409637155186850213682522142927749122", - "data": "VGhpcyBpcyBhIHRlc3QgZnJvbSBLaW5lc2lzIEFuYWx5dGljcw==" - } - ] -} diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv-python/lambda_function.py b/examples/apps/kinesis-firehose-apachelog-to-csv-python/lambda_function.py deleted file mode 100644 index 29e410465f..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv-python/lambda_function.py +++ /dev/null @@ -1,40 +0,0 @@ -from __future__ import print_function - -import base64 -import re - -print('Loading function') - - -def lambda_handler(event, context): - output = [] - succeeded_record_cnt = 0 - failed_record_cnt = 0 - - for record in event['records']: - print(record['recordId']) - payload = base64.b64decode(record['data']) - - p = re.compile(r"^([\d.]+) (\S+) (\S+) \[([\w:/]+\s[\+\-]\d{4})\] \"(.+?)\" (\d{3}) (\d+)") - m = p.match(payload) - if m: - succeeded_record_cnt += 1 - output_payload = m.group(1) + ',' + m.group(2) + ',' + m.group(3) + ',' + m.group(4) + ',' + m.group(5) + ',' + m.group(6) + ',' + m.group(7) + '\n' - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(output_payload) - } - else: - print('Parsing failed') - failed_record_cnt += 1 - output_record = { - 'recordId': record['recordId'], - 'result': 'ProcessingFailed', - 'data': record['data'] - } - - output.append(output_record) - - print('Processing completed. Successful records {}, Failed records {}.'.format(succeeded_record_cnt, failed_record_cnt)) - return {'records': output} diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv-python/license.txt b/examples/apps/kinesis-firehose-apachelog-to-csv-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv-python/readme b/examples/apps/kinesis-firehose-apachelog-to-csv-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv-python/requirements.txt b/examples/apps/kinesis-firehose-apachelog-to-csv-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv-python/template.yaml b/examples/apps/kinesis-firehose-apachelog-to-csv-python/template.yaml deleted file mode 100644 index 2f8bd41f2f..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv-python/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from - Apache Common Log format to CSV. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseapachelogtocsvpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records - from Apache Common Log format to CSV. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv/index.js b/examples/apps/kinesis-firehose-apachelog-to-csv/index.js deleted file mode 100644 index 689409c0de..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv/index.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; -console.log('Loading function'); - -/* Apache Log format parser */ -const parser = /^([\d.]+) (\S+) (\S+) \[([\w:/]+\s[\+\-]\d{4})\] "(.+?)" (\d{3}) (\d+)/; - -exports.handler = (event, context, callback) => { - let success = 0; // Number of valid entries found - let failure = 0; // Number of invalid entries found - - /* Process the list of records and transform them */ - const output = event.records.map((record) => { - const entry = (Buffer.from(record.data, 'base64')).toString('utf8'); - const match = parser.exec(entry); - if (match) { - /* Prepare CSV version from Apache log data */ - const result = `${match[1]},${match[2]},${match[3]},${match[4]},${match[5]},${match[6]},${match[7]}\n`; - const payload = (Buffer.from(result, 'utf8')).toString('base64'); - success++; - return { - recordId: record.recordId, - result: 'Ok', - data: payload, - }; - } else { - /* Failed event, notify the error and leave the record intact */ - failure++; - return { - recordId: record.recordId, - result: 'ProcessingFailed', - data: record.data, - }; - } - }); - console.log(`Processing completed. Successful records ${success}, Failed records ${failure}.`); - callback(null, { records: output }); -}; diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv/license.txt b/examples/apps/kinesis-firehose-apachelog-to-csv/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv/readme b/examples/apps/kinesis-firehose-apachelog-to-csv/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv/template.yaml b/examples/apps/kinesis-firehose-apachelog-to-csv/template.yaml deleted file mode 100644 index a4194a3d12..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from - Apache Common Log format to CSV. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseapachelogtocsv: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records - from Apache Common Log format to CSV. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-csv/testEvent.json b/examples/apps/kinesis-firehose-apachelog-to-csv/testEvent.json deleted file mode 100644 index daf0b4243d..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-csv/testEvent.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "invocationId": "invocationIdExample", - "region": "us-east-1", - "records": [ - { - "recordId": "49546986683135544286507457936321625675700192471156785154", - "approximateArrivalTimestamp": 1495072949453, - "data": "NjQuMjQyLjg4LjEwIC0gLSBbMDcvTWFyLzIwMDQ6MTY6MTA6MDIgLTA4MDBdICJHRVQgL21haWxtYW4vbGlzdGluZm8vaHNkaXZpc2lvbiBIVFRQLzEuMSIgMjAwIDYyOTE==" - } - ] -} diff --git a/examples/apps/kinesis-firehose-apachelog-to-json-python/lambda_function.py b/examples/apps/kinesis-firehose-apachelog-to-json-python/lambda_function.py deleted file mode 100644 index 81701416ca..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json-python/lambda_function.py +++ /dev/null @@ -1,90 +0,0 @@ -from __future__ import print_function - -import base64 -import json -import re -from dateutil.parser import parse -from datetime import datetime, tzinfo, timedelta - -print('Loading function') - - -class UTC(tzinfo): - """UTC""" - - def utcoffset(self, dt): - return timedelta(0) - - def tzname(self, dt): - return "UTC" - - def dst(self, dt): - return timedelta(0) - -utc = UTC() - - -def lambda_handler(event, context): - output = [] - succeeded_record_cnt = 0 - failed_record_cnt = 0 - - safe_string_to_int = lambda x: int(x) if x.isdigit() else x - - for record in event['records']: - print(record['recordId']) - payload = base64.b64decode(record['data']) - p = re.compile(r"^([\d.]+) (\S+) (\S+) \[([\w:/]+)(\s[\+\-]\d{4}){0,1}\] \"(.+?)\" (\d{3}) (\d+)") - m = p.match(payload) - if m: - succeeded_record_cnt += 1 - - ts = m.group(4) - try: - d = parse(ts.replace(':', ' ', 1)) - ts = d.isoformat() - except: - print('Parsing the timestamp to date failed.') - - data_field = { - 'host': m.group(1), - 'ident': m.group(2), - 'authuser': m.group(3), - '@timestamp': ts, - 'request': m.group(6), - 'response': safe_string_to_int(m.group(7)), - 'bytes': safe_string_to_int(m.group(8)) - } - - if m.group(6) and len(m.group(6).split()) > 1: - data_field['verb'] = m.group(6).split()[0] - - # If time offset is present, add the timezone and @timestamp_utc fields - if m.group(5): - data_field['timezone'] = m.group(5).strip() - try: - ts_with_offset = m.group(4) + m.group(5) - d = parse(ts_with_offset.replace(':', ' ', 1)) - utc_d = d.astimezone(utc) - data_field['@timestamp_utc'] = utc_d.isoformat() - except: - print('Calculating UTC time failed.') - - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(json.dumps(data_field)) - } - else: - print('Parsing failed') - failed_record_cnt += 1 - output_record = { - 'recordId': record['recordId'], - 'result': 'ProcessingFailed', - 'data': record['data'] - } - - output.append(output_record) - - print('Processing completed. Successful records {}, Failed records {}.'.format(succeeded_record_cnt, failed_record_cnt)) - return {'records': output} diff --git a/examples/apps/kinesis-firehose-apachelog-to-json-python/license.txt b/examples/apps/kinesis-firehose-apachelog-to-json-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-json-python/requirements.txt b/examples/apps/kinesis-firehose-apachelog-to-json-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-firehose-apachelog-to-json-python/template.yaml b/examples/apps/kinesis-firehose-apachelog-to-json-python/template.yaml deleted file mode 100644 index b43fb035bf..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json-python/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from - Apache Common Log format to JSON. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseapachelogtojsonpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records - from Apache Common Log format to JSON. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-json/index.js b/examples/apps/kinesis-firehose-apachelog-to-json/index.js deleted file mode 100644 index 7b5efe8b5d..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json/index.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict'; -console.log('Loading function'); - -/* Apache Log format parser */ -const parser = /^([\d.]+) (\S+) (\S+) \[([\w:/]+)(\s[\+\-]\d{4}){0,1}\] "(.+?)" (\d{3}) (\d+)/; - -exports.handler = (event, context, callback) => { - let success = 0; // Number of valid entries found - let failure = 0; // Number of invalid entries found - - /* Process the list of records and transform them */ - const output = event.records.map((record) => { - const entry = (Buffer.from(record.data, 'base64')).toString('utf8'); - const match = parser.exec(entry); - if (match) { - /* Prepare JSON version from Apache log data */ - const safeStringToInt = (strVal) => { - if (isNaN(Number(strVal))) { - return strVal; - } else { - return Number(strVal); - } - }; - const formatDate = (strVal) => strVal.replace(/\//g, ' ').replace(':', ' '); - - const result = { - host: match[1], - ident: match[2], - authuser: match[3], - request: match[6], - response: safeStringToInt(match[7]), - bytes: safeStringToInt(match[8]), - }; - - if (match[6] && match[6].split(' ').length > 1) { - result.verb = match[6].split(' ')[0]; - } - - let isoTs = match[4]; - try { - isoTs = new Date(formatDate(isoTs)).toISOString(); - } catch (err) { - console.log('Parsing the timestamp to date failed.'); - } - result['@timestamp'] = isoTs; - - if (match[5]) { - const timezone = match[5].trim(); - result.timezone = timezone; - try { - const ts = formatDate(match[4]); - const combinedTs = `${ts} ${timezone}`; - result['@timestamp_utc'] = new Date(combinedTs).toISOString(); - } catch (err) { - console.log('Calculating UTC time failed.'); - } - } - - const payload = (Buffer.from(JSON.stringify(result), 'utf8')).toString('base64'); - success++; - return { - recordId: record.recordId, - result: 'Ok', - data: payload, - }; - } else { - /* Failed event, notify the error and leave the record intact */ - failure++; - return { - recordId: record.recordId, - result: 'ProcessingFailed', - data: record.data, - }; - } - }); - console.log(`Processing completed. Successful records ${success}, Failed records ${failure}.`); - callback(null, { records: output }); -}; diff --git a/examples/apps/kinesis-firehose-apachelog-to-json/license.txt b/examples/apps/kinesis-firehose-apachelog-to-json/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-json/template.yaml b/examples/apps/kinesis-firehose-apachelog-to-json/template.yaml deleted file mode 100644 index 849b876dca..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from - Apache Common Log format to JSON. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseapachelogtojson: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records - from Apache Common Log format to JSON. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-apachelog-to-json/testEvent.json b/examples/apps/kinesis-firehose-apachelog-to-json/testEvent.json deleted file mode 100644 index daf0b4243d..0000000000 --- a/examples/apps/kinesis-firehose-apachelog-to-json/testEvent.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "invocationId": "invocationIdExample", - "region": "us-east-1", - "records": [ - { - "recordId": "49546986683135544286507457936321625675700192471156785154", - "approximateArrivalTimestamp": 1495072949453, - "data": "NjQuMjQyLjg4LjEwIC0gLSBbMDcvTWFyLzIwMDQ6MTY6MTA6MDIgLTA4MDBdICJHRVQgL21haWxtYW4vbGlzdGluZm8vaHNkaXZpc2lvbiBIVFRQLzEuMSIgMjAwIDYyOTE==" - } - ] -} diff --git a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/index.js b/examples/apps/kinesis-firehose-cloudwatch-logs-processor/index.js deleted file mode 100644 index bb59e9b5ad..0000000000 --- a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/index.js +++ /dev/null @@ -1,90 +0,0 @@ -/* -For processing data sent to Firehose by Cloudwatch Logs subscription filters. - -Cloudwatch Logs sends to Firehose records that look like this: - -{ - "messageType": "DATA_MESSAGE", - "owner": "123456789012", - "logGroup": "log_group_name", - "logStream": "log_stream_name", - "subscriptionFilters": [ - "subscription_filter_name" - ], - "logEvents": [ - { - "id": "01234567890123456789012345678901234567890123456789012345", - "timestamp": 1510109208016, - "message": "log message 1" - }, - { - "id": "01234567890123456789012345678901234567890123456789012345", - "timestamp": 1510109208017, - "message": "log message 2" - } - ... - ] -} - -The data is additionally compressed with GZIP. - -The code below will: - -1) Gunzip the data -2) Parse the json -3) Set the result to ProcessingFailed for any record whose messageType is not DATA_MESSAGE, thus redirecting them to the - processing error output. Such records do not contain any log events. You can modify the code to set the result to - Dropped instead to get rid of these records completely. -4) For records whose messageType is DATA_MESSAGE, extract the individual log events from the logEvents field, and pass - each one to the transformLogEvent method. You can modify the transformLogEvent method to perform custom - transformations on the log events. -5) Concatenate the result from (4) together and set the result as the data of the record returned to Firehose. Note that - this step will not add any delimiters. Delimiters should be appended by the logic within the transformLogEvent - method. -*/ - -'use strict'; - -const zlib = require('zlib'); - -/** - * logEvent has this format: - * - * { - * "id": "01234567890123456789012345678901234567890123456789012345", - * "timestamp": 1510109208016, - * "message": "log message 1" - * } - * - * The default implementation below just extracts the message and appends a newline to it. - * - * The result must be returned in a Promise. - */ -function transformLogEvent(logEvent) { - return Promise.resolve(`${logEvent.message}\n`); -} - -exports.handler = (event, context, callback) => { - Promise.all(event.records.map(r => { - const buffer = new Buffer(r.data, 'base64'); - const decompressed = zlib.gunzipSync(buffer); - const data = JSON.parse(decompressed); - if (data.messageType !== 'DATA_MESSAGE') { - return Promise.resolve({ - recordId: r.recordId, - result: 'ProcessingFailed', - }); - } else { - const promises = data.logEvents.map(transformLogEvent); - return Promise.all(promises).then(transformed => { - const payload = transformed.reduce((a, v) => a + v, ''); - const encoded = new Buffer(payload).toString('base64'); - return { - recordId: r.recordId, - result: 'Ok', - data: encoded, - }; - }); - } - })).then(recs => callback(null, { records: recs })); -}; diff --git a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/lib/mysplunklogger.js b/examples/apps/kinesis-firehose-cloudwatch-logs-processor/lib/mysplunklogger.js deleted file mode 100644 index 2e5467bf75..0000000000 --- a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } else { - console.log('Sent'); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/template.yaml b/examples/apps/kinesis-firehose-cloudwatch-logs-processor/template.yaml deleted file mode 100644 index 8645e1cf82..0000000000 --- a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that extracts individual log events from records sent by Cloudwatch Logs subscription filters. -Parameters: - BucketNameParameter: - Type: String -Resources: - kinesisfirehosecloudwatchlogsprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that extracts individual log events from records sent by Cloudwatch Logs subscription filters. - MemorySize: 128 - Timeout: 3 - Policies: - - S3CrudPolicy: - BucketName: !Ref BucketNameParameter diff --git a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/testEvent.json b/examples/apps/kinesis-firehose-cloudwatch-logs-processor/testEvent.json deleted file mode 100644 index 9a562a0ac8..0000000000 --- a/examples/apps/kinesis-firehose-cloudwatch-logs-processor/testEvent.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "records": [ - { - "recordId": "49578734086442259037497492980620233840400173390482112514000000", - "data": "H4sIAAAAAAAAADWO0QqCMBiFX2XsWiJFi7wLUW8sIYUuQmLpnxvpJttMQnz3Ztrlxzmc8424BaVIDfmnA+zjID3nlzS5n8IsO8YhtrAYOMg5aURfDUSXNBG1MkEj6liKvjPZQpmWQNoFVf9QpWSdZoJHrNEgFfZvxa8XvoHrGUfMqqWumdHQpDVjtmdvHc91dwdn71p/vVngmqBVD616PgoolC/Ga0SBNJoi8USVWWKczM8oYhKoULDBUzF9Aeua5yHsAAAA", - "approximateArrivalTimestamp": 1510254469499 - }, - { - "recordId": "49578734086442259037497492980621442766219788363254202370000000", - "data": "H4sIAAAAAAAAAJWRTWsbMRCG/8ueLZjRjL5yc9NNLnZDapemlFAkrTYstb3Lep0Qgv97x00KgTSHnAQzmkeP3nmqtmW/j3dl/TiU6qz6PF/Pfy3r1Wp+WVezqn/YlVHK2pK3Hr0Jxkt5099djv1hkE7uh0eVHzZqE7epiarb3fe/ixzDYVJoELRhssYQqsXLlEJ3jd8//biy4QYWz7jVNJa4/TDveQwV+qsada0v/HnthLg/pH0eu2Hq+t1Ft5nKuK/Ofn4EvnpDUAu7Xi6/LL9en3/z1e1f7fq+7KYT+qnqGrEnsi54AGS2wbHWxjCjoWAYGawmzawByIG3Dp0JzjOxsaI8dbKJKW4l1BcTdgg+zP5tSPCeQ/Bso/I+o+I2kUptjgrRlQyasslUHWdvZRwGJ4+HYJGCtiKgQTYKSJ4gODLgAkpFk3f0rkyA1zLGSsvoVsVCRTFakUkNqKxt1IyFc8T/y0gEmoHZo5a/W9HhU0TeWHMyIJaoQC6zDvC+DL6WSW3MqZSkiolJcWoalWybJSNIJTXcRgjV8fb4BwwLrNzwAgAA", - "approximateArrivalTimestamp": 1510254473773 - }, - { - "recordId": "49578734086442259037497492980622651692039402992428908546000000", - "data": "H4sIAAAAAAAAAJWRbWsbMQyA/8t9jkGSJdnut2zLCiXZyJKyZaMM352vHEty4e7SUkr++9yXwUbXD8Vgg2w9eizdF7s0DPE6re8OqTgrPkzX05+L2Wo1PZ8Vk6K73ac+h0mtV49egvgc3nbX5313POSbqjvcmep2a7ZxV9bRtPub7lfKx+E4GhQEErYqYtHMn7MMuiV+fbf5rOEbzJ9wq7FPcfdm3lOaNReXyws/3cw2fvk9A4djOVR9exjbbv+x3Y6pH4qzH29hr14QzFzXi8WnxZfl+0tfXD1az27SfnxA3xdtneWtVRc8ADJrcEwkwoxigzAyiBNxzkJuIxGrei+g3gbgrDy2eRBj3OWePpuwQ/Bh8mdAGR+J69pJMFXKihwTGJ+aYJArpkjYQB2K0+SljMPgyFIIijaQgs2BAMEyexbns1NeoqpsCV+VCfCPTOVLLgUMU4h5S5UpE4BRm6ROqCEF/r8MExBDro3ED0XBMigFVM0iQlkRvZLml9a/LoN/yzSYKoIKTOmVTf6VNTHZxkjTIElkqlCL09XpN5PgkxrvAgAA", - "approximateArrivalTimestamp": 1510254474027 - }, - { - "recordId": "49578734086442259037497492980623860617859017621603614722000000", - "data": "H4sIAAAAAAAAAJWRW28aQQyF/8s+M9J47LHHeaMtzUOhEQXSVlVUDctstCqwCJZEUcR/r3OpFCnNQ17mcjw+8+n4vtqUwyFfl/ndrlRn1afhfPh7MprNhuejalB1t9uyNzkwJk6QosZk8rq7Pt93x51V6m535+rbtVvnzXKVXbu96f4U23bH3kEEHyIhx4jgxs9dDmQK3z/8vGD94cdPdrN+X/Lm3X5PbcHp5QLkYrqYLC6/mOHhuDzU+3bXt932c7vuy/5Qnf16j/fslYMb83wy+Tr5Nv24SNXVI/Xopmz7B+v7ql0ZPCKLJu+BiFUohBiJIKJGAvIkSTgpsU8aVBNangymsCH3rQ2izxvL9JmEBOzh4N+AzL6gX3JD7CLn4kg8OiVduahNkIa0BtbqNHgNI6AS0P5kQA3sUcA4IDCElCBKwgdgiCoI+CaM+pcwbAVfN8F5r2owGV0OdpWkS8kp52a1/D8MBR8sDUoQKDIbDnqlhAgQLTMWz8YbRQT92zDwEkbIQ10YHUZbKGfvUmrAIWodih2btKpOV6e/zXGIX+8CAAA=", - "approximateArrivalTimestamp": 1510254474388 - } - ], - "region": "us-east-1", - "deliveryStreamArn": "arn:aws:firehose:us-east-1:123456789012:deliverystream/copy-cwl-lambda-invoke-input-151025436553-Firehose-8KILJ01Q5OBN", - "invocationId": "a7234216-12b6-4bc0-96d7-82606c0e80cf" -} diff --git a/examples/apps/kinesis-firehose-process-record-python/lambda_function.py b/examples/apps/kinesis-firehose-process-record-python/lambda_function.py deleted file mode 100644 index 87c7cad350..0000000000 --- a/examples/apps/kinesis-firehose-process-record-python/lambda_function.py +++ /dev/null @@ -1,26 +0,0 @@ -from __future__ import print_function - -import base64 - -print('Loading function') - - -def lambda_handler(event, context): - output = [] - - for record in event['records']: - print(record['recordId']) - payload = base64.b64decode(record['data']) - - # Do custom processing on the payload here - - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(payload) - } - output.append(output_record) - - print('Successfully processed {} records.'.format(len(event['records']))) - - return {'records': output} diff --git a/examples/apps/kinesis-firehose-process-record-python/license.txt b/examples/apps/kinesis-firehose-process-record-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-process-record-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-python/readme b/examples/apps/kinesis-firehose-process-record-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-process-record-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-python/requirements.txt b/examples/apps/kinesis-firehose-process-record-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-firehose-process-record-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-firehose-process-record-python/template.yaml b/examples/apps/kinesis-firehose-process-record-python/template.yaml deleted file mode 100644 index 4b9abb500e..0000000000 --- a/examples/apps/kinesis-firehose-process-record-python/template.yaml +++ /dev/null @@ -1,29 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that accesses the records in the - input and returns them with a processing status. Use this processor for any - custom transformation logic. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseprocessrecordpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that accesses the records in - the input and returns them with a processing status. Use this processor - for any custom transformation logic. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/lambda_function.py b/examples/apps/kinesis-firehose-process-record-streams-as-source-python/lambda_function.py deleted file mode 100644 index cf09f0b657..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/lambda_function.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import print_function - -import base64 - -print('Loading function') - - -def lambda_handler(event, context): - output = [] - - for record in event['records']: - print(record['recordId']) - payload = base64.b64decode(record['data']) - print(record['recordId']) - - # Print stream as source only data here - kinesisMetadata = record['kinesisRecordMetadata'] - print(kinesisMetadata['sequenceNumber']) - print(kinesisMetadata['subsequenceNumber']) - print(kinesisMetadata['partitionKey']) - print(kinesisMetadata['shardId']) - print(kinesisMetadata['approximateArrivalTimestamp']) - - # Do custom processing on the payload here - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(payload) - } - output.append(output_record) - - print('Successfully processed {} records.'.format(len(event['records']))) - - return {'records': output} diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/license.txt b/examples/apps/kinesis-firehose-process-record-streams-as-source-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/readme b/examples/apps/kinesis-firehose-process-record-streams-as-source-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/requirements.txt b/examples/apps/kinesis-firehose-process-record-streams-as-source-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/template.yaml b/examples/apps/kinesis-firehose-process-record-streams-as-source-python/template.yaml deleted file mode 100644 index c2322b5836..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source-python/template.yaml +++ /dev/null @@ -1,25 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that accesses the Kinesis Streams records in the input and returns them with a processing status. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseprocessrecordstreamsassourcepython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that accesses the Kinesis Streams records in the input and returns them with a processing status. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source/index.js b/examples/apps/kinesis-firehose-process-record-streams-as-source/index.js deleted file mode 100644 index 57909fcf58..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source/index.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - /*Print streams as source only data here*/ - event.records.forEach((record) => { - console.log(record.kinesisRecordMetadata.sequenceNumber); - console.log(record.kinesisRecordMetadata.subsequenceNumber); - console.log(record.kinesisRecordMetadata.partitionKey); - console.log(record.kinesisRecordMetadata.shardId); - console.log(record.kinesisRecordMetadata.approximateArrivalTimestamp); - }); - /* Process the list of records and transform them */ - const output = event.records.map((record) => ({ - /* This transformation is the "identity" transformation, the data is left intact */ - recordId: record.recordId, - result: 'Ok', - data: record.data, - })); - console.log(`Processing completed. Successful records ${output.length}.`); - callback(null, { records: output }); -}; diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source/license.txt b/examples/apps/kinesis-firehose-process-record-streams-as-source/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source/readme b/examples/apps/kinesis-firehose-process-record-streams-as-source/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source/template.yaml b/examples/apps/kinesis-firehose-process-record-streams-as-source/template.yaml deleted file mode 100644 index 7818071502..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source/template.yaml +++ /dev/null @@ -1,25 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that accesses the Kinesis Streams records in the input and returns them with a processing status. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseprocessrecordstreamsassource: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that accesses the Kinesis Streams records in the input and returns them with a processing status. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record-streams-as-source/testEvent.json b/examples/apps/kinesis-firehose-process-record-streams-as-source/testEvent.json deleted file mode 100644 index deb243e4f9..0000000000 --- a/examples/apps/kinesis-firehose-process-record-streams-as-source/testEvent.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "invocationId": "invocationIdExample", - "deliverySteamArn": "arn:aws:kinesis:EXAMPLE", - "region": "us-east-1", - "records": [ - { - "recordId": "49546986683135544286507457936321625675700192471156785154", - "approximateArrivalTimestamp": 1495072949453, - "kinesisRecordMetadata": { - "sequenceNumber": "49545115243490985018280067714973144582180062593244200961", - "subsequenceNumber": "123456", - "partitionKey": "partitionKey-03", - "shardId": "shardId-000000000000", - "approximateArrivalTimestamp": 1495072949453 - }, - "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=" - } - ] -} diff --git a/examples/apps/kinesis-firehose-process-record/index.js b/examples/apps/kinesis-firehose-process-record/index.js deleted file mode 100644 index 3a85a3bb68..0000000000 --- a/examples/apps/kinesis-firehose-process-record/index.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - /* Process the list of records and transform them */ - const output = event.records.map((record) => ({ - /* This transformation is the "identity" transformation, the data is left intact */ - recordId: record.recordId, - result: 'Ok', - data: record.data, - })); - console.log(`Processing completed. Successful records ${output.length}.`); - callback(null, { records: output }); -}; diff --git a/examples/apps/kinesis-firehose-process-record/license.txt b/examples/apps/kinesis-firehose-process-record/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-process-record/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record/readme b/examples/apps/kinesis-firehose-process-record/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-process-record/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-process-record/template.yaml b/examples/apps/kinesis-firehose-process-record/template.yaml deleted file mode 100644 index 8f1ed4c262..0000000000 --- a/examples/apps/kinesis-firehose-process-record/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that accesses the records in the - input and returns them with a processing status. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehoseprocessrecord: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that accesses the records in - the input and returns them with a processing status. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-csv-python/lambda_function.py b/examples/apps/kinesis-firehose-syslog-to-csv-python/lambda_function.py deleted file mode 100644 index c422705d27..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv-python/lambda_function.py +++ /dev/null @@ -1,48 +0,0 @@ -from __future__ import print_function - -import base64 -import re - -print('Loading function') - - -def lambda_handler(event, context): - output = [] - succeeded_record_cnt = 0 - failed_record_cnt = 0 - - for record in event['records']: - print(record['recordId']) - payload = base64.b64decode(record['data']) - - regex_string = (r"^((?:\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?" - r"|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b\s+(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])\s+" - r"(?:(?:2[0123]|[01]?[0-9]):(?:[0-5][0-9]):(?:(?:[0-5]?[0-9]|60)(?:[:\.,][0-9]+)?)))) (?:<(?:[0-9]+).(?:[0-9]+)> )" - r"?((?:[a-zA-Z0-9._-]+)) ([\w\._/%-]+)(?:\[((?:[1-9][0-9]*))\])?: (.*)") - p = re.compile(regex_string) - m = p.match(payload) - - def str_or_null(s): - return s or 'null' - - if m: - succeeded_record_cnt += 1 - output_payload = m.group(1) + ',' + m.group(2) + ',' + m.group(3) + ',' + str_or_null(m.group(4)) + ',' + m.group(5) + '\n' - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(output_payload) - } - else: - print('Parsing failed') - failed_record_cnt += 1 - output_record = { - 'recordId': record['recordId'], - 'result': 'ProcessingFailed', - 'data': record['data'] - } - - output.append(output_record) - - print('Processing completed. Successful records {}, Failed records {}.'.format(succeeded_record_cnt, failed_record_cnt)) - return {'records': output} diff --git a/examples/apps/kinesis-firehose-syslog-to-csv-python/license.txt b/examples/apps/kinesis-firehose-syslog-to-csv-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-csv-python/readme b/examples/apps/kinesis-firehose-syslog-to-csv-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-csv-python/requirements.txt b/examples/apps/kinesis-firehose-syslog-to-csv-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-firehose-syslog-to-csv-python/template.yaml b/examples/apps/kinesis-firehose-syslog-to-csv-python/template.yaml deleted file mode 100644 index 39ed34d0da..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv-python/template.yaml +++ /dev/null @@ -1,25 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to CSV. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehosesyslogtocsvpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to CSV. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter diff --git a/examples/apps/kinesis-firehose-syslog-to-csv/index.js b/examples/apps/kinesis-firehose-syslog-to-csv/index.js deleted file mode 100644 index 7095a5a55e..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv/index.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict'; -console.log('Loading function'); - -/* Syslog format parser */ -const parser = '^((?:\\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?' + - '|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\\b\\s+(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])\\s+' + - '(?:(?:2[0123]|[01]?[0-9]):(?:[0-5][0-9]):(?:(?:[0-5]?[0-9]|60)(?:[:\\.,][0-9]+)?)))) (?:<(?:[0-9]+).(?:[0-9]+)> ' + - ')?((?:[a-zA-Z0-9._-]+)) ([\\w\\._/%-]+)(?:\\[((?:[1-9][0-9]*))\\])?: (.*)'; - -exports.handler = (event, context, callback) => { - let success = 0; // Number of valid entries found - let failure = 0; // Number of invalid entries found - - /* Process the list of records and transform them */ - const output = event.records.map((record) => { - // Kinesis data is base64 encoded so decode here - console.log(record.recordId); - const payload = (Buffer.from(record.data, 'base64')).toString('ascii'); - const match = payload.match(parser); - if (match) { - /* Prepare CSV version from Syslog log data */ - const result = `${match[1]},${match[2]},${match[3]},${match[4]},${match[5]},${match[6]}\n`; - success++; - return { - recordId: record.recordId, - result: 'Ok', - data: (Buffer.from(result, 'utf8')).toString('base64'), - }; - } else { - /* Failed event, notify the error and leave the record intact */ - failure++; - return { - recordId: record.recordId, - result: 'ProcessingFailed', - data: record.data, - }; - } - }); - console.log(`Processing completed. Successful records ${success}, Failed records ${failure}.`); - callback(null, { records: output }); -}; - diff --git a/examples/apps/kinesis-firehose-syslog-to-csv/license.txt b/examples/apps/kinesis-firehose-syslog-to-csv/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-csv/readme b/examples/apps/kinesis-firehose-syslog-to-csv/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-csv/template.yaml b/examples/apps/kinesis-firehose-syslog-to-csv/template.yaml deleted file mode 100644 index 172222e591..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv/template.yaml +++ /dev/null @@ -1,25 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to CSV. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehosesyslogtocsv: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to CSV. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-csv/testEvent.json b/examples/apps/kinesis-firehose-syslog-to-csv/testEvent.json deleted file mode 100644 index 8d867f528b..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-csv/testEvent.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "invocationId": "fir", - "region": "us-east-1", - "records": [ - { - "recordId": "49546986683135544286507457936321625675700192471156785154", - "approximateArrivalTimestamp": 1495072949453, - "data": "SmFuIDEyIDA2OjMwOjAwIDEuMi4zLjQgYXBhY2hlX3NlcnZlcjogMS4yLjMuNCAtIC0gWzEyL0phbi8yMDExOjA2OjI5OjU5ICswMTAwXSAiR0VUIC9mb28vYmFyLmh0bWwgSFRUUC8xLjEiIDMwMSA5NiAiLSIgIk1vemlsbGEvNS4wIChXaW5kb3dzOyBVOyBXaW5kb3dzIE5UIDUuMTsgZnI7IHJ2OjEuOS4yLjEyKSBHZWNrby8yMDEwMTAyNiBGaXJlZm94LzMuNi4xMiAoIC5ORVQgQ0xSIDMuNS4zMDcyOSkiIFBJRCAxODkwNCBUaW1lIFRha2VuIDA=" - }, - { - "recordId": "49546986683135544286507457936321625675700192471156785154", - "approximateArrivalTimestamp": "2012-04-23T18:25:43.511Z", - "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0IDEyMy4=" - } - ] -} diff --git a/examples/apps/kinesis-firehose-syslog-to-json-python/lambda_function.py b/examples/apps/kinesis-firehose-syslog-to-json-python/lambda_function.py deleted file mode 100644 index f55a7e62a6..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json-python/lambda_function.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import print_function - -import base64 -import json -import re - -print('Loading function') - - -def lambda_handler(event, context): - output = [] - succeeded_record_cnt = 0 - failed_record_cnt = 0 - - for record in event['records']: - print(record['recordId']) - payload = base64.b64decode(record['data']) - - regex_string = (r"^((?:\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?" - r"|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b\s+(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])\s+" - r"(?:(?:2[0123]|[01]?[0-9]):(?:[0-5][0-9]):(?:(?:[0-5]?[0-9]|60)(?:[:\.,][0-9]+)?)))) (?:<(?:[0-9]+).(?:[0-9]+)> )" - r"?((?:[a-zA-Z0-9._-]+)) ([\w\._/%-]+)(?:\[((?:[1-9][0-9]*))\])?: (.*)") - p = re.compile(regex_string) - m = p.match(payload) - if m: - succeeded_record_cnt += 1 - data_field = { - 'timestamp': m.group(1), - 'hostname': m.group(2), - 'program': m.group(3), - 'processid': m.group(4), - 'message': m.group(5) - } - output_record = { - 'recordId': record['recordId'], - 'result': 'Ok', - 'data': base64.b64encode(json.dumps(data_field)) - } - else: - print('Parsing failed') - failed_record_cnt += 1 - output_record = { - 'recordId': record['recordId'], - 'result': 'ProcessingFailed', - 'data': record['data'] - } - - output.append(output_record) - - print('Processing completed. Successful records {}, Failed records {}.'.format(succeeded_record_cnt, failed_record_cnt)) - return {'records': output} diff --git a/examples/apps/kinesis-firehose-syslog-to-json-python/license.txt b/examples/apps/kinesis-firehose-syslog-to-json-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-json-python/readme b/examples/apps/kinesis-firehose-syslog-to-json-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-json-python/requirements.txt b/examples/apps/kinesis-firehose-syslog-to-json-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-firehose-syslog-to-json-python/template.yaml b/examples/apps/kinesis-firehose-syslog-to-json-python/template.yaml deleted file mode 100644 index 56ee835a6e..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json-python/template.yaml +++ /dev/null @@ -1,26 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to JSON. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehosesyslogtojsonpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to JSON. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - diff --git a/examples/apps/kinesis-firehose-syslog-to-json/index.js b/examples/apps/kinesis-firehose-syslog-to-json/index.js deleted file mode 100644 index dafabc05ca..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json/index.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; -console.log('Loading function'); - -/* Syslog format parser */ -const parser = '^((?:\\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?' + - '|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\\b\\s+(?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])\\s+' + - '(?:(?:2[0123]|[01]?[0-9]):(?:[0-5][0-9]):(?:(?:[0-5]?[0-9]|60)(?:[:\\.,][0-9]+)?)))) (?:<(?:[0-9]+).(?:[0-9]+)> ' + - ')?((?:[a-zA-Z0-9._-]+)) ([\\w\\._/%-]+)(?:\\[((?:[1-9][0-9]*))\\])?: (.*)'; - -exports.handler = (event, context, callback) => { - let success = 0; // Number of valid entries found - let failure = 0; // Number of invalid entries found - - /* Process the list of records and transform them */ - const output = event.records.map((record) => { - // Kinesis data is base64 encoded so decode here - console.log(record.recordId); - const payload = new Buffer(record.data, 'base64').toString('ascii'); - console.log('Decoded payload:', payload); - const match = payload.match(parser); - if (match) { - /* Prepare JSON version from Syslog log data */ - const result = { - timestamp: match[1], - hostname: match[2], - program: match[3], - processid: match[4], - message: match[5], - }; - success++; - return { - recordId: record.recordId, - result: 'Ok', - data: new Buffer(JSON.stringify(result)).toString('base64'), - }; - } else { - /* Failed event, notify the error and leave the record intact */ - failure++; - return { - recordId: record.recordId, - result: 'ProcessingFailed', - data: record.data, - }; - } - }); - console.log(`Processing completed. Successful records ${success}, Failed records ${failure}.`); - callback(null, { records: output }); -}; - diff --git a/examples/apps/kinesis-firehose-syslog-to-json/license.txt b/examples/apps/kinesis-firehose-syslog-to-json/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-json/readme b/examples/apps/kinesis-firehose-syslog-to-json/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-firehose-syslog-to-json/template.yaml b/examples/apps/kinesis-firehose-syslog-to-json/template.yaml deleted file mode 100644 index 6d2cbfadac..0000000000 --- a/examples/apps/kinesis-firehose-syslog-to-json/template.yaml +++ /dev/null @@ -1,25 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to JSON. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisfirehosesyslogtojson: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon Kinesis Firehose stream processor that converts input records from RFC3164 Syslog format to JSON. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter diff --git a/examples/apps/kinesis-process-record-python/lambda_function.py b/examples/apps/kinesis-process-record-python/lambda_function.py deleted file mode 100644 index a2b01ca29a..0000000000 --- a/examples/apps/kinesis-process-record-python/lambda_function.py +++ /dev/null @@ -1,15 +0,0 @@ -from __future__ import print_function - -import base64 -import json - -print('Loading function') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - for record in event['Records']: - # Kinesis data is base64 encoded so decode here - payload = base64.b64decode(record['kinesis']['data']) - print("Decoded payload: " + payload) - return 'Successfully processed {} records.'.format(len(event['Records'])) diff --git a/examples/apps/kinesis-process-record-python/license.txt b/examples/apps/kinesis-process-record-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-process-record-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-process-record-python/readme b/examples/apps/kinesis-process-record-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-process-record-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-process-record-python/requirements.txt b/examples/apps/kinesis-process-record-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/kinesis-process-record-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/kinesis-process-record-python/template.yaml b/examples/apps/kinesis-process-record-python/template.yaml deleted file mode 100644 index fe189893a9..0000000000 --- a/examples/apps/kinesis-process-record-python/template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon Kinesis stream processor that logs the data being published. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisprocessrecordpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: An Amazon Kinesis stream processor that logs the data being published. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - Events: - Kinesis1: - Type: Kinesis - Properties: - Stream: - 'Fn::GetAtt': - - KinesisStream1 - - Arn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - KinesisStream1: - Type: 'AWS::Kinesis::Stream' - Properties: - ShardCount: 1 diff --git a/examples/apps/kinesis-process-record/index.js b/examples/apps/kinesis-process-record/index.js deleted file mode 100644 index 4edfe7111b..0000000000 --- a/examples/apps/kinesis-process-record/index.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - event.Records.forEach((record) => { - // Kinesis data is base64 encoded so decode here - const payload = new Buffer(record.kinesis.data, 'base64').toString('ascii'); - console.log('Decoded payload:', payload); - }); - callback(null, `Successfully processed ${event.Records.length} records.`); -}; diff --git a/examples/apps/kinesis-process-record/license.txt b/examples/apps/kinesis-process-record/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/kinesis-process-record/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/kinesis-process-record/readme b/examples/apps/kinesis-process-record/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/kinesis-process-record/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/kinesis-process-record/template.yaml b/examples/apps/kinesis-process-record/template.yaml deleted file mode 100644 index 8e767d7f45..0000000000 --- a/examples/apps/kinesis-process-record/template.yaml +++ /dev/null @@ -1,37 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon Kinesis stream processor that logs the data being published. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - kinesisprocessrecord: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: An Amazon Kinesis stream processor that logs the data being published. - MemorySize: 128 - Timeout: 3 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - Events: - Kinesis1: - Type: Kinesis - Properties: - Stream: - 'Fn::GetAtt': - - KinesisStream1 - - Arn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - KinesisStream1: - Type: 'AWS::Kinesis::Stream' - Properties: - ShardCount: 1 diff --git a/examples/apps/lambda-canary-python3/lambda_function.py b/examples/apps/lambda-canary-python3/lambda_function.py deleted file mode 100644 index ff7dbe9f33..0000000000 --- a/examples/apps/lambda-canary-python3/lambda_function.py +++ /dev/null @@ -1,32 +0,0 @@ - -import os -from datetime import datetime -from urllib.request import urlopen - -SITE = os.environ['site'] # URL of the site to check, stored in the site environment variable -EXPECTED = os.environ['expected'] # String expected to be on the page, stored in the expected environment variable - - -def validate(res): - '''Return False to trigger the canary - - Currently this simply checks whether the EXPECTED string is present. - However, you could modify this to perform any number of arbitrary - checks on the contents of SITE. - ''' - return EXPECTED in res - - -def lambda_handler(event, context): - print('Checking {} at {}...'.format(SITE, event['time'])) - try: - if not validate(str(urlopen(SITE).read())): - raise Exception('Validation failed') - except: - print('Check failed!') - raise - else: - print('Check passed!') - return event['time'] - finally: - print('Check complete at {}'.format(str(datetime.now()))) diff --git a/examples/apps/lambda-canary-python3/license.txt b/examples/apps/lambda-canary-python3/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lambda-canary-python3/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lambda-canary-python3/readme b/examples/apps/lambda-canary-python3/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lambda-canary-python3/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lambda-canary-python3/requirements.txt b/examples/apps/lambda-canary-python3/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/lambda-canary-python3/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/lambda-canary-python3/template.yaml b/examples/apps/lambda-canary-python3/template.yaml deleted file mode 100644 index ffa60a506d..0000000000 --- a/examples/apps/lambda-canary-python3/template.yaml +++ /dev/null @@ -1,24 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Performs a periodic check of the given site, erroring out on test failure.' -Parameters: - FunctionNameParameter: - Type: String -Resources: - lambdacanarypython3: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python3.6 - CodeUri: . - Description: >- - Performs a periodic check of the given site, erroring out on test failure. - MemorySize: 128 - Timeout: 10 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - Environment: - Variables: - site: 'https://www.amazon.com/' - expected: Online Shopping diff --git a/examples/apps/lambda-canary/lambda_function.py b/examples/apps/lambda-canary/lambda_function.py deleted file mode 100644 index 20f8799116..0000000000 --- a/examples/apps/lambda-canary/lambda_function.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import print_function - -import os -from datetime import datetime -from urllib2 import urlopen - -SITE = os.environ['site'] # URL of the site to check, stored in the site environment variable, e.g. https://aws.amazon.com -EXPECTED = os.environ['expected'] # String expected to be on the page, stored in the expected environment variable, e.g. Amazon - - -def validate(res): - '''Return False to trigger the canary - - Currently this simply checks whether the EXPECTED string is present. - However, you could modify this to perform any number of arbitrary - checks on the contents of SITE. - ''' - return EXPECTED in res - - -def lambda_handler(event, context): - print('Checking {} at {}...'.format(SITE, event['time'])) - try: - if not validate(urlopen(SITE).read()): - raise Exception('Validation failed') - except: - print('Check failed!') - raise - else: - print('Check passed!') - return event['time'] - finally: - print('Check complete at {}'.format(str(datetime.now()))) diff --git a/examples/apps/lambda-canary/license.txt b/examples/apps/lambda-canary/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lambda-canary/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lambda-canary/readme b/examples/apps/lambda-canary/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lambda-canary/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lambda-canary/requirements.txt b/examples/apps/lambda-canary/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/lambda-canary/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/lambda-canary/template.yaml b/examples/apps/lambda-canary/template.yaml deleted file mode 100644 index 82ce5c4f0d..0000000000 --- a/examples/apps/lambda-canary/template.yaml +++ /dev/null @@ -1,28 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Performs a periodic check of the given site, erroring out on test failure.' -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - lambdacanary: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - Performs a periodic check of the given site, erroring out on test failure. - MemorySize: 128 - Timeout: 10 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - Environment: - Variables: - site: - expected: diff --git a/examples/apps/lambda-test-harness/index.js b/examples/apps/lambda-test-harness/index.js deleted file mode 100644 index 5c1cc42ca7..0000000000 --- a/examples/apps/lambda-test-harness/index.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict'; - -/** - * Provides a simple framework for conducting various tests of your Lambda - * functions. Make sure to include permissions for `lambda:InvokeFunction` - * and `dynamodb:PutItem` in your execution role! - */ -const AWS = require('aws-sdk'); -const doc = require('dynamodb-doc'); - -const lambda = new AWS.Lambda({ apiVersion: '2015-03-31' }); -const dynamo = new doc.DynamoDB(); - - -// Asynchronously runs a given function X times -const asyncAll = (opts) => { - let i = -1; - const next = () => { - i++; - if (i === opts.times) { - opts.done(); - return; - } - opts.fn(next, i); - }; - next(); -}; - - -/** - * Will invoke the given function and write its result to the DynamoDB table - * `event.resultsTable`. This table must have a hash key string of "testId" - * and range key number of "iteration". Specify a unique `event.testId` to - * differentiate each unit test run. - */ -const unit = (event, callback) => { - const lambdaParams = { - FunctionName: event.function, - Payload: JSON.stringify(event.event), - }; - lambda.invoke(lambdaParams, (err, data) => { - if (err) { - return callback(err); - } - // Write result to Dynamo - const dynamoParams = { - TableName: event.resultsTable, - Item: { - testId: event.testId, - iteration: event.iteration || 0, - result: data.Payload, - passed: !Object.prototype.hasOwnProperty.call(JSON.parse(data.Payload), 'errorMessage'), - }, - }; - dynamo.putItem(dynamoParams, callback); - }); -}; - -/** - * Will invoke the given function asynchronously `event.iterations` times. - */ -const load = (event, callback) => { - const payload = event.event; - asyncAll({ - times: event.iterations, - fn: (next, i) => { - payload.iteration = i; - const lambdaParams = { - FunctionName: event.function, - InvocationType: 'Event', - Payload: JSON.stringify(payload), - }; - lambda.invoke(lambdaParams, next); - }, - done: () => callback(null, 'Load test complete'), - }); -}; - - -const ops = { - unit, - load, -}; - -/** - * Pass the test type (currently either "unit" or "load") as `event.operation`, - * the name of the Lambda function to test as `event.function`, and the event - * to invoke this function with as `event.event`. - * - * See the individual test methods above for more information about each - * test type. - */ -exports.handler = (event, context, callback) => { - if (Object.prototype.hasOwnProperty.call(ops, event.operation)) { - ops[event.operation](event, callback); - } else { - callback(`Unrecognized operation "${event.operation}"`); - } -}; diff --git a/examples/apps/lambda-test-harness/license.txt b/examples/apps/lambda-test-harness/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lambda-test-harness/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lambda-test-harness/readme b/examples/apps/lambda-test-harness/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lambda-test-harness/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lambda-test-harness/template.yaml b/examples/apps/lambda-test-harness/template.yaml deleted file mode 100644 index 628ef46dd0..0000000000 --- a/examples/apps/lambda-test-harness/template.yaml +++ /dev/null @@ -1,25 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Provides a simple framework for conducting various tests of your Lambda functions. -Parameters: - FunctionNameParameter: - Type: String - TableNameParameter: - Type: String -Resources: - lambdatestharness: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Provides a simple framework for conducting various tests of your Lambda functions. - MemorySize: 128 - Timeout: 60 - Policies: - - LambdaInvokePolicy: - FunctionName: !Ref FunctionNameParameter - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/lex-book-trip-python/lambda_function.py b/examples/apps/lex-book-trip-python/lambda_function.py deleted file mode 100644 index 06e71284b3..0000000000 --- a/examples/apps/lex-book-trip-python/lambda_function.py +++ /dev/null @@ -1,519 +0,0 @@ -""" -This sample demonstrates an implementation of the Lex Code Hook Interface -in order to serve a sample bot which manages reservations for hotel rooms and car rentals. -Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console -as part of the 'BookTrip' template. - -For instructions on how to set up and test this bot, as well as additional samples, -visit the Lex Getting Started documentation http://docs.aws.amazon.com/lex/latest/dg/getting-started.html. -""" - -import json -import datetime -import dateutil.parser -import logging - -logger = logging.getLogger() -logger.setLevel(logging.DEBUG) - - -# --- Helpers that build all of the responses --- - - -def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'ElicitSlot', - 'intentName': intent_name, - 'slots': slots, - 'slotToElicit': slot_to_elicit, - 'message': message - } - } - - -def confirm_intent(session_attributes, intent_name, slots, message): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'ConfirmIntent', - 'intentName': intent_name, - 'slots': slots, - 'message': message - } - } - - -def close(session_attributes, fulfillment_state, message): - response = { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'Close', - 'fulfillmentState': fulfillment_state, - 'message': message - } - } - - return response - - -def delegate(session_attributes, slots): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'Delegate', - 'slots': slots - } - } - - -# --- Helper Functions --- - - -def safe_int(n): - """ - Safely convert n value to int. - """ - if n is not None: - return int(n) - return n - - -def try_ex(func): - """ - Call passed in function in try block. If KeyError is encountered return None. - This function is intended to be used to safely access dictionary. - - Note that this function would have negative impact on performance. - """ - - try: - return func() - except KeyError: - return None - - -def generate_car_price(location, days, age, car_type): - """ - Generates a number within a reasonable range that might be expected for a flight. - The price is fixed for a given pair of locations. - """ - - car_types = ['economy', 'standard', 'midsize', 'full size', 'minivan', 'luxury'] - base_location_cost = 0 - for i in range(len(location)): - base_location_cost += ord(location.lower()[i]) - 97 - - age_multiplier = 1.10 if age < 25 else 1 - # Select economy is car_type is not found - if car_type not in car_types: - car_type = car_types[0] - - return days * ((100 + base_location_cost) + ((car_types.index(car_type) * 50) * age_multiplier)) - - -def generate_hotel_price(location, nights, room_type): - """ - Generates a number within a reasonable range that might be expected for a hotel. - The price is fixed for a pair of location and roomType. - """ - - room_types = ['queen', 'king', 'deluxe'] - cost_of_living = 0 - for i in range(len(location)): - cost_of_living += ord(location.lower()[i]) - 97 - - return nights * (100 + cost_of_living + (100 + room_types.index(room_type.lower()))) - - -def isvalid_car_type(car_type): - car_types = ['economy', 'standard', 'midsize', 'full size', 'minivan', 'luxury'] - return car_type.lower() in car_types - - -def isvalid_city(city): - valid_cities = ['new york', 'los angeles', 'chicago', 'houston', 'philadelphia', 'phoenix', 'san antonio', - 'san diego', 'dallas', 'san jose', 'austin', 'jacksonville', 'san francisco', 'indianapolis', - 'columbus', 'fort worth', 'charlotte', 'detroit', 'el paso', 'seattle', 'denver', 'washington dc', - 'memphis', 'boston', 'nashville', 'baltimore', 'portland'] - return city.lower() in valid_cities - - -def isvalid_room_type(room_type): - room_types = ['queen', 'king', 'deluxe'] - return room_type.lower() in room_types - - -def isvalid_date(date): - try: - dateutil.parser.parse(date) - return True - except ValueError: - return False - - -def get_day_difference(later_date, earlier_date): - later_datetime = dateutil.parser.parse(later_date).date() - earlier_datetime = dateutil.parser.parse(earlier_date).date() - return abs(later_datetime - earlier_datetime).days - - -def add_days(date, number_of_days): - new_date = dateutil.parser.parse(date).date() - new_date += datetime.timedelta(days=number_of_days) - return new_date.strftime('%Y-%m-%d') - - -def build_validation_result(isvalid, violated_slot, message_content): - return { - 'isValid': isvalid, - 'violatedSlot': violated_slot, - 'message': {'contentType': 'PlainText', 'content': message_content} - } - - -def validate_book_car(slots): - pickup_city = try_ex(lambda: slots['PickUpCity']) - pickup_date = try_ex(lambda: slots['PickUpDate']) - return_date = try_ex(lambda: slots['ReturnDate']) - driver_age = safe_int(try_ex(lambda: slots['DriverAge'])) - car_type = try_ex(lambda: slots['CarType']) - - if pickup_city and not isvalid_city(pickup_city): - return build_validation_result( - False, - 'PickUpCity', - 'We currently do not support {} as a valid destination. Can you try a different city?'.format(pickup_city) - ) - - if pickup_date: - if not isvalid_date(pickup_date): - return build_validation_result(False, 'PickUpDate', 'I did not understand your departure date. When would you like to pick up your car rental?') - - if dateutil.parser.parse(pickup_date) < datetime.datetime.today(): - return build_validation_result(False, 'PickUpDate', 'Your pick up date is in the past! Can you try a different date?') - - if return_date: - if not isvalid_date(return_date): - return build_validation_result(False, 'ReturnDate', 'I did not understand your return date. When would you like to return your car rental?') - - if pickup_date and return_date: - if dateutil.parser.parse(pickup_date) >= dateutil.parser.parse(return_date): - return build_validation_result(False, 'ReturnDate', 'Your return date must be after your pick up date. Can you try a different return date?') - - if get_day_difference(pickup_date, return_date) > 30: - return build_validation_result(False, 'ReturnDate', 'You can reserve a car for up to thirty days. Can you try a different return date?') - - if driver_age is not None and driver_age < 18: - return build_validation_result( - False, - 'DriverAge', - 'Your driver must be at least eighteen to rent a car. Can you provide the age of a different driver?' - ) - - if car_type and not isvalid_car_type(car_type): - return build_validation_result( - False, - 'CarType', - 'I did not recognize that model. What type of car would you like to rent? ' - 'Popular cars are economy, midsize, or luxury') - - return {'isValid': True} - - -def validate_hotel(slots): - location = try_ex(lambda: slots['Location']) - checkin_date = try_ex(lambda: slots['CheckInDate']) - nights = safe_int(try_ex(lambda: slots['Nights'])) - room_type = try_ex(lambda: slots['RoomType']) - - if location and not isvalid_city(location): - return build_validation_result( - False, - 'Location', - 'We currently do not support {} as a valid destination. Can you try a different city?'.format(location) - ) - - if checkin_date: - if not isvalid_date(checkin_date): - return build_validation_result(False, 'CheckInDate', 'I did not understand your check in date. When would you like to check in?') - - if dateutil.parser.parse(checkin_date) < datetime.datetime.today(): - return build_validation_result(False, 'CheckInDate', 'Your check in date is in the past! Can you try a different date?') - - if nights is not None and (nights < 1 or nights > 30): - return build_validation_result( - False, - 'Nights', - 'You can make a reservations for from one to thirty nights. How many nights would you like to stay for?' - ) - - if room_type and not isvalid_room_type(room_type): - return build_validation_result(False, 'RoomType', 'I did not recognize that room type. Would you like to stay in a queen, king, or deluxe room?') - - return {'isValid': True} - - -""" --- Functions that control the bot's behavior --- """ - - -def book_hotel(intent_request): - """ - Performs dialog management and fulfillment for booking a hotel. - - Beyond fulfillment, the implementation for this intent demonstrates the following: - 1) Use of elicitSlot in slot validation and re-prompting - 2) Use of sessionAttributes to pass information that can be used to guide conversation - """ - - location = try_ex(lambda: intent_request['currentIntent']['slots']['Location']) - checkin_date = try_ex(lambda: intent_request['currentIntent']['slots']['CheckInDate']) - nights = safe_int(try_ex(lambda: intent_request['currentIntent']['slots']['Nights'])) - - room_type = try_ex(lambda: intent_request['currentIntent']['slots']['RoomType']) - session_attributes = intent_request['sessionAttributes'] - - # Load confirmation history and track the current reservation. - reservation = json.dumps({ - 'ReservationType': 'Hotel', - 'Location': location, - 'RoomType': room_type, - 'CheckInDate': checkin_date, - 'Nights': nights - }) - - session_attributes['currentReservation'] = reservation - - if intent_request['invocationSource'] == 'DialogCodeHook': - # Validate any slots which have been specified. If any are invalid, re-elicit for their value - validation_result = validate_hotel(intent_request['currentIntent']['slots']) - if not validation_result['isValid']: - slots = intent_request['currentIntent']['slots'] - slots[validation_result['violatedSlot']] = None - - return elicit_slot( - session_attributes, - intent_request['currentIntent']['name'], - slots, - validation_result['violatedSlot'], - validation_result['message'] - ) - - # Otherwise, let native DM rules determine how to elicit for slots and prompt for confirmation. Pass price - # back in sessionAttributes once it can be calculated; otherwise clear any setting from sessionAttributes. - if location and checkin_date and nights and room_type: - # The price of the hotel has yet to be confirmed. - price = generate_hotel_price(location, nights, room_type) - session_attributes['currentReservationPrice'] = price - else: - try_ex(lambda: session_attributes.pop('currentReservationPrice')) - - session_attributes['currentReservation'] = reservation - return delegate(session_attributes, intent_request['currentIntent']['slots']) - - # Booking the hotel. In a real application, this would likely involve a call to a backend service. - logger.debug('bookHotel under={}'.format(reservation)) - - try_ex(lambda: session_attributes.pop('currentReservationPrice')) - try_ex(lambda: session_attributes.pop('currentReservation')) - session_attributes['lastConfirmedReservation'] = reservation - - return close( - session_attributes, - 'Fulfilled', - { - 'contentType': 'PlainText', - 'content': 'Thanks, I have placed your reservation. Please let me know if you would like to book a car ' - 'rental, or another hotel.' - } - ) - - -def book_car(intent_request): - """ - Performs dialog management and fulfillment for booking a car. - - Beyond fulfillment, the implementation for this intent demonstrates the following: - 1) Use of elicitSlot in slot validation and re-prompting - 2) Use of sessionAttributes to pass information that can be used to guide conversation - """ - slots = intent_request['currentIntent']['slots'] - pickup_city = slots['PickUpCity'] - pickup_date = slots['PickUpDate'] - return_date = slots['ReturnDate'] - driver_age = slots['DriverAge'] - car_type = slots['CarType'] - confirmation_status = intent_request['currentIntent']['confirmationStatus'] - session_attributes = intent_request['sessionAttributes'] - last_confirmed_reservation = try_ex(lambda: session_attributes['lastConfirmedReservation']) - if last_confirmed_reservation: - last_confirmed_reservation = json.loads(last_confirmed_reservation) - confirmation_context = try_ex(lambda: session_attributes['confirmationContext']) - - # Load confirmation history and track the current reservation. - reservation = json.dumps({ - 'ReservationType': 'Car', - 'PickUpCity': pickup_city, - 'PickUpDate': pickup_date, - 'ReturnDate': return_date, - 'CarType': car_type - }) - session_attributes['currentReservation'] = reservation - - if pickup_city and pickup_date and return_date and driver_age and car_type: - # Generate the price of the car in case it is necessary for future steps. - price = generate_car_price(pickup_city, get_day_difference(pickup_date, return_date), driver_age, car_type) - session_attributes['currentReservationPrice'] = price - - if intent_request['invocationSource'] == 'DialogCodeHook': - # Validate any slots which have been specified. If any are invalid, re-elicit for their value - validation_result = validate_book_car(intent_request['currentIntent']['slots']) - if not validation_result['isValid']: - slots[validation_result['violatedSlot']] = None - return elicit_slot( - session_attributes, - intent_request['currentIntent']['name'], - slots, - validation_result['violatedSlot'], - validation_result['message'] - ) - - # Determine if the intent (and current slot settings) has been denied. The messaging will be different - # if the user is denying a reservation he initiated or an auto-populated suggestion. - if confirmation_status == 'Denied': - # Clear out auto-population flag for subsequent turns. - try_ex(lambda: session_attributes.pop('confirmationContext')) - try_ex(lambda: session_attributes.pop('currentReservation')) - if confirmation_context == 'AutoPopulate': - return elicit_slot( - session_attributes, - intent_request['currentIntent']['name'], - { - 'PickUpCity': None, - 'PickUpDate': None, - 'ReturnDate': None, - 'DriverAge': None, - 'CarType': None - }, - 'PickUpCity', - { - 'contentType': 'PlainText', - 'content': 'Where would you like to make your car reservation?' - } - ) - - return delegate(session_attributes, intent_request['currentIntent']['slots']) - - if confirmation_status == 'None': - # If we are currently auto-populating but have not gotten confirmation, keep requesting for confirmation. - if (not pickup_city and not pickup_date and not return_date and not driver_age and not car_type)\ - or confirmation_context == 'AutoPopulate': - if last_confirmed_reservation and try_ex(lambda: last_confirmed_reservation['ReservationType']) == 'Hotel': - # If the user's previous reservation was a hotel - prompt for a rental with - # auto-populated values to match this reservation. - session_attributes['confirmationContext'] = 'AutoPopulate' - return confirm_intent( - session_attributes, - intent_request['currentIntent']['name'], - { - 'PickUpCity': last_confirmed_reservation['Location'], - 'PickUpDate': last_confirmed_reservation['CheckInDate'], - 'ReturnDate': add_days( - last_confirmed_reservation['CheckInDate'], last_confirmed_reservation['Nights'] - ), - 'CarType': None, - 'DriverAge': None - }, - { - 'contentType': 'PlainText', - 'content': 'Is this car rental for your {} night stay in {} on {}?'.format( - last_confirmed_reservation['Nights'], - last_confirmed_reservation['Location'], - last_confirmed_reservation['CheckInDate'] - ) - } - ) - - # Otherwise, let native DM rules determine how to elicit for slots and/or drive confirmation. - return delegate(session_attributes, intent_request['currentIntent']['slots']) - - # If confirmation has occurred, continue filling any unfilled slot values or pass to fulfillment. - if confirmation_status == 'Confirmed': - # Remove confirmationContext from sessionAttributes so it does not confuse future requests - try_ex(lambda: session_attributes.pop('confirmationContext')) - if confirmation_context == 'AutoPopulate': - if not driver_age: - return elicit_slot( - session_attributes, - intent_request['currentIntent']['name'], - intent_request['currentIntent']['slots'], - 'DriverAge', - { - 'contentType': 'PlainText', - 'content': 'How old is the driver of this car rental?' - } - ) - elif not car_type: - return elicit_slot( - session_attributes, - intent_request['currentIntent']['name'], - intent_request['currentIntent']['slots'], - 'CarType', - { - 'contentType': 'PlainText', - 'content': 'What type of car would you like? Popular models are ' - 'economy, midsize, and luxury.' - } - ) - - return delegate(session_attributes, intent_request['currentIntent']['slots']) - - # Booking the car. In a real application, this would likely involve a call to a backend service. - logger.debug('bookCar at={}'.format(reservation)) - del session_attributes['currentReservationPrice'] - del session_attributes['currentReservation'] - session_attributes['lastConfirmedReservation'] = reservation - return close( - session_attributes, - 'Fulfilled', - { - 'contentType': 'PlainText', - 'content': 'Thanks, I have placed your reservation.' - } - ) - - -# --- Intents --- - - -def dispatch(intent_request): - """ - Called when the user specifies an intent for this bot. - """ - - logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name'])) - - intent_name = intent_request['currentIntent']['name'] - - # Dispatch to your bot's intent handlers - if intent_name == 'BookHotel': - return book_hotel(intent_request) - elif intent_name == 'BookCar': - return book_car(intent_request) - - raise Exception('Intent with name ' + intent_name + ' not supported') - - -# --- Main handler --- - - -def lambda_handler(event, context): - """ - Route the incoming request based on intent. - The JSON body of the request is provided in the event slot. - """ - - logger.debug('event.bot.name={}'.format(event['bot']['name'])) - - return dispatch(event) diff --git a/examples/apps/lex-book-trip-python/license.txt b/examples/apps/lex-book-trip-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lex-book-trip-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lex-book-trip-python/readme b/examples/apps/lex-book-trip-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lex-book-trip-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lex-book-trip-python/requirements.txt b/examples/apps/lex-book-trip-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/lex-book-trip-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/lex-book-trip-python/template.yaml b/examples/apps/lex-book-trip-python/template.yaml deleted file mode 100644 index f128a3d3b5..0000000000 --- a/examples/apps/lex-book-trip-python/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Book details of a visit, using Amazon Lex to perform natural language - understanding -Parameters: - KeyIdParameter: - Type: String -Resources: - lexbooktrippython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - Book details of a visit, using Amazon Lex to perform natural language - understanding - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/lex-book-trip/index.js b/examples/apps/lex-book-trip/index.js deleted file mode 100644 index 62d05a418a..0000000000 --- a/examples/apps/lex-book-trip/index.js +++ /dev/null @@ -1,401 +0,0 @@ -'use strict'; - - /** - * This sample demonstrates an implementation of the Lex Code Hook Interface - * in order to serve a sample bot which manages reservations for hotel rooms and car rentals. - * Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console - * as part of the 'BookTrip' template. - * - * For instructions on how to set up and test this bot, as well as additional samples, - * visit the Lex Getting Started documentation. - */ - - // --------------- Helpers that build all of the responses ----------------------- - -function elicitSlot(sessionAttributes, intentName, slots, slotToElicit, message) { - return { - sessionAttributes, - dialogAction: { - type: 'ElicitSlot', - intentName, - slots, - slotToElicit, - message, - }, - }; -} - -function confirmIntent(sessionAttributes, intentName, slots, message) { - return { - sessionAttributes, - dialogAction: { - type: 'ConfirmIntent', - intentName, - slots, - message, - }, - }; -} - -function close(sessionAttributes, fulfillmentState, message) { - return { - sessionAttributes, - dialogAction: { - type: 'Close', - fulfillmentState, - message, - }, - }; -} - -function delegate(sessionAttributes, slots) { - return { - sessionAttributes, - dialogAction: { - type: 'Delegate', - slots, - }, - }; -} - -// ---------------- Helper Functions -------------------------------------------------- - -// Generates a number within a reasonable range that might be expected for a flight. -// The price is fixed for a given pair of locations. -function generateCarPrice(location, days, age, carType) { - const carTypes = ['economy', 'standard', 'midsize', 'full size', 'minivan', 'luxury']; - let baseLocationCost = 0; - for (let i = 0; i < location.length; i++) { - baseLocationCost += location.toLowerCase().charCodeAt(i) - 97; - } - const ageMultiplier = (age < 25) ? 1.10 : 1; - return days * ((100 + baseLocationCost) + ((carTypes.indexOf(carType) * 50) * ageMultiplier)); -} - -// Generates a number within a reasonable range that might be expected for a hotel. -// The price is fixed for a pair of location and roomType. -function generateHotelPrice(location, nights, roomType) { - const roomTypes = ['queen', 'king', 'deluxe']; - let costOfLiving = 0; - for (let i = 0; i < location.length; i++) { - costOfLiving += location.toLowerCase().charCodeAt(i) - 97; - } - return nights * (100 + costOfLiving + (100 + roomTypes.indexOf(roomType.toLowerCase()))); -} - -function isValidCarType(carType) { - const carTypes = ['economy', 'standard', 'midsize', 'full size', 'minivan', 'luxury']; - return (carTypes.indexOf(carType.toLowerCase()) > -1); -} - -function isValidCity(city) { - const validCities = ['new york', 'los angeles', 'chicago', 'houston', 'philadelphia', 'phoenix', 'san antonio', 'san diego', 'dallas', 'san jose', - 'austin', 'jacksonville', 'san francisco', 'indianapolis', 'columbus', 'fort worth', 'charlotte', 'detroit', 'el paso', 'seattle', 'denver', 'washington dc', - 'memphis', 'boston', 'nashville', 'baltimore', 'portland']; - return (validCities.indexOf(city.toLowerCase()) > -1); -} - -function isValidRoomType(roomType) { - const roomTypes = ['queen', 'king', 'deluxe']; - return (roomTypes.indexOf(roomType.toLowerCase()) > -1); -} - -function isValidDate(date) { - return !(isNaN(Date.parse(date))); -} - -function getDayDifference(earlierDate, laterDate) { - const laterDateInDaysSinceEpoch = new Date(laterDate).getTime() / 86400000; - const earlierDateInDaysSinceEpoch = new Date(earlierDate).getTime() / 86400000; - return Number(laterDateInDaysSinceEpoch - earlierDateInDaysSinceEpoch).toFixed(0); -} - -function addDays(date, numberOfDays) { - const newDate = new Date(date); - newDate.setTime(newDate.getTime() + (86400000 * numberOfDays)); - return `${newDate.getFullYear()}-${newDate.getMonth() + 1}-${newDate.getDate()}`; -} - -function buildValidationResult(isValid, violatedSlot, messageContent) { - return { - isValid, - violatedSlot, - message: { contentType: 'PlainText', content: messageContent }, - }; -} - -function validateBookCar(slots) { - const pickUpCity = slots.PickUpCity; - const pickUpDate = slots.PickUpDate; - const returnDate = slots.ReturnDate; - const driverAge = slots.DriverAge; - const carType = slots.CarType; - - if (pickUpCity && !isValidCity(pickUpCity)) { - return buildValidationResult(false, 'PickUpCity', `We currently do not support ${pickUpCity} as a valid destination. Can you try a different city?`); - } - - if (pickUpDate) { - if (!isValidDate(pickUpDate)) { - return buildValidationResult(false, 'PickUpDate', 'I did not understand your departure date. When would you like to pick up your car rental?'); - } - if (new Date(pickUpDate) < new Date()) { - return buildValidationResult(false, 'PickUpDate', 'Your pick up date is in the past! Can you try a different date?'); - } - } - - if (returnDate) { - if (!isValidDate(returnDate)) { - return buildValidationResult(false, 'ReturnDate', 'I did not understand your return date. When would you like to return your car rental?'); - } - } - - if (pickUpDate && returnDate) { - if (new Date(pickUpDate) >= new Date(returnDate)) { - return buildValidationResult(false, 'ReturnDate', 'Your return date must be after your pick up date. Can you try a different return date?'); - } - if (getDayDifference(pickUpDate, returnDate) > 30) { - return buildValidationResult(false, 'ReturnDate', 'You can reserve a car for up to thirty days. Can you try a different return date?'); - } - } - - if (driverAge != null && driverAge < 18) { - return buildValidationResult(false, 'DriverAge', 'Your driver must be at least eighteen to rent a car. Can you provide the age of a different driver?'); - } - - if (carType && !isValidCarType(carType)) { - return buildValidationResult(false, 'CarType', 'I did not recognize that model. What type of car would you like to rent? Popular cars are economy, midsize, or luxury'); - } - - return { isValid: true }; -} - -function validateHotel(slots) { - const location = slots.Location; - const checkInDate = slots.CheckInDate; - const nights = slots.Nights; - const roomType = slots.RoomType; - - if (location && !isValidCity(location)) { - return buildValidationResult(false, 'Location', `We currently do not support ${location} as a valid destination. Can you try a different city?`); - } - - if (checkInDate) { - if (!isValidDate(checkInDate)) { - return buildValidationResult(false, 'CheckInDate', 'I did not understand your check in date. When would you like to check in?'); - } - if (new Date(checkInDate) < new Date()) { - return buildValidationResult(false, 'CheckInDate', 'Your check in date is in the past! Can you try a different date?'); - } - } - - if (nights != null && (nights < 1 || nights > 30)) { - return buildValidationResult(false, 'Nights', 'You can make a reservations for from one to thirty nights. How many nights would you like to stay for?'); - } - - if (roomType && !isValidRoomType(roomType)) { - return buildValidationResult(false, 'RoomType', 'I did not recognize that room type. Would you like to stay in a queen, king, or deluxe room?'); - } - - return { isValid: true }; -} - -/** - * Performs dialog management and fulfillment for booking a hotel. - * - * Beyond fulfillment, the implementation for this intent demonstrates the following: - * 1) Use of elicitSlot in slot validation and re-prompting - * 2) Use of sessionAttributes to pass information that can be used to guide conversation - */ -function bookHotel(intentRequest, callback) { - const location = intentRequest.currentIntent.slots.Location; - const checkInDate = intentRequest.currentIntent.slots.CheckInDate; - const nights = intentRequest.currentIntent.slots.Nights; - const roomType = intentRequest.currentIntent.slots.RoomType; - const sessionAttributes = intentRequest.sessionAttributes; - - // Load confirmation history and track the current reservation. - const reservation = String(JSON.stringify({ ReservationType: 'Hotel', Location: location, RoomType: roomType, CheckInDate: checkInDate, Nights: nights })); - sessionAttributes.currentReservation = reservation; - - if (intentRequest.invocationSource === 'DialogCodeHook') { - // Validate any slots which have been specified. If any are invalid, re-elicit for their value - const validationResult = validateHotel(intentRequest.currentIntent.slots); - if (!validationResult.isValid) { - const slots = intentRequest.currentIntent.slots; - slots[`${validationResult.violatedSlot}`] = null; - callback(elicitSlot(sessionAttributes, intentRequest.currentIntent.name, - slots, validationResult.violatedSlot, validationResult.message)); - return; - } - - // Otherwise, let native DM rules determine how to elicit for slots and prompt for confirmation. Pass price back in sessionAttributes once it can be calculated; otherwise clear any setting from sessionAttributes. - if (location && checkInDate && nights != null && roomType) { - // The price of the hotel has yet to be confirmed. - const price = generateHotelPrice(location, nights, roomType); - sessionAttributes.currentReservationPrice = price; - } else { - delete sessionAttributes.currentReservationPrice; - } - sessionAttributes.currentReservation = reservation; - callback(delegate(sessionAttributes, intentRequest.currentIntent.slots)); - return; - } - - // Booking the hotel. In a real application, this would likely involve a call to a backend service. - console.log(`bookHotel under=${reservation}`); - - delete sessionAttributes.currentReservationPrice; - delete sessionAttributes.currentReservation; - sessionAttributes.lastConfirmedReservation = reservation; - - callback(close(sessionAttributes, 'Fulfilled', - { contentType: 'PlainText', content: 'Thanks, I have placed your reservation. Please let me know if you would like to book a car rental, or another hotel.' })); -} - -/** - * Performs dialog management and fulfillment for booking a hotel. - * - * Beyond fulfillment, the implementation for this intent demonstrates the following: - * 1) Use of elicitSlot in slot validation and re-prompting - * 2) Use of confirmIntent to support the confirmation of inferred slot values - */ -function bookCar(intentRequest, callback) { - const slots = intentRequest.currentIntent.slots; - const pickUpCity = slots.PickUpCity; - const pickUpDate = slots.PickUpDate; - const returnDate = slots.ReturnDate; - const driverAge = slots.DriverAge; - const carType = slots.CarType; - const confirmationStatus = intentRequest.currentIntent.confirmationStatus; - const sessionAttributes = intentRequest.sessionAttributes; - const lastConfirmedReservation = sessionAttributes.lastConfirmedReservation ? JSON.parse(sessionAttributes.lastConfirmedReservation) : null; - const confirmationContext = sessionAttributes.confirmationContext; - - // Load confirmation history and track the current reservation. - const reservation = String(JSON.stringify({ ReservationType: 'Car', PickUpCity: pickUpCity, PickUpDate: pickUpDate, ReturnDate: returnDate, CarType: carType })); - sessionAttributes.currentReservation = reservation; - - if (pickUpCity && pickUpDate && returnDate && driverAge != null && carType) { - // Generate the price of the car in case it is necessary for future steps. - const price = generateCarPrice(pickUpCity, getDayDifference(pickUpDate, returnDate), driverAge, carType); - sessionAttributes.currentReservationPrice = price; - } - - if (intentRequest.invocationSource === 'DialogCodeHook') { - // Validate any slots which have been specified. If any are invalid, re-elicit for their value - const validationResult = validateBookCar(intentRequest.currentIntent.slots); - if (!validationResult.isValid) { - slots[`${validationResult.violatedSlot}`] = null; - callback(elicitSlot(sessionAttributes, intentRequest.currentIntent.name, - slots, validationResult.violatedSlot, validationResult.message)); - return; - } - - // Determine if the intent (and current slot settings) has been denied. The messaging will be different if the user is denying a reservation he initiated or an auto-populated suggestion. - if (confirmationStatus === 'Denied') { - // Clear out auto-population flag for subsequent turns. - delete sessionAttributes.confirmationContext; - delete sessionAttributes.currentReservation; - if (confirmationContext === 'AutoPopulate') { - callback(elicitSlot(sessionAttributes, intentRequest.currentIntent.name, { PickUpCity: null, PickUpDate: null, ReturnDate: null, DriverAge: null, CarType: null }, 'PickUpCity', - { contentType: 'PlainText', content: 'Where would you like to make your car reservation?' })); - return; - } - callback(delegate(sessionAttributes, intentRequest.currentIntent.slots)); - return; - } - - if (confirmationStatus === 'None') { - // If we are currently auto-populating but have not gotten confirmation, keep requesting for confirmation. - if ((!pickUpCity && !pickUpDate && !returnDate && driverAge == null && !carType) || confirmationContext === 'AutoPopulate') { - if (lastConfirmedReservation && lastConfirmedReservation.ReservationType === 'Hotel') { - //If the user's previous reservation was a hotel - prompt for a rental with auto-populated values to match this reservation. - sessionAttributes.confirmationContext = 'AutoPopulate'; - callback(confirmIntent(sessionAttributes, intentRequest.currentIntent.name, - { - PickUpCity: lastConfirmedReservation.Location, - PickUpDate: lastConfirmedReservation.CheckInDate, - ReturnDate: `${addDays(lastConfirmedReservation.CheckInDate, lastConfirmedReservation.Nights)}`, - CarType: null, - DriverAge: null, - }, - { contentType: 'PlainText', content: `Is this car rental for your ${lastConfirmedReservation.Nights} night stay in ${lastConfirmedReservation.Location} on ${lastConfirmedReservation.CheckInDate}?` })); - return; - } - } - // Otherwise, let native DM rules determine how to elicit for slots and/or drive confirmation. - callback(delegate(sessionAttributes, intentRequest.currentIntent.slots)); - return; - } - - // If confirmation has occurred, continue filling any unfilled slot values or pass to fulfillment. - if (confirmationStatus === 'Confirmed') { - // Remove confirmationContext from sessionAttributes so it does not confuse future requests - delete sessionAttributes.confirmationContext; - if (confirmationContext === 'AutoPopulate') { - if (!driverAge) { - callback(elicitSlot(sessionAttributes, intentRequest.currentIntent.name, intentRequest.currentIntent.slots, 'DriverAge', - { contentType: 'PlainText', content: 'How old is the driver of this car rental?' })); - return; - } else if (!carType) { - callback(elicitSlot(sessionAttributes, intentRequest.currentIntent.name, intentRequest.currentIntent.slots, 'CarType', - { contentType: 'PlainText', content: 'What type of car would you like? Popular models are economy, midsize, and luxury.' })); - return; - } - } - callback(delegate(sessionAttributes, intentRequest.currentIntent.slots)); - return; - } - } - - // Booking the car. In a real application, this would likely involve a call to a backend service. - console.log(`bookCar at=${reservation}`); - delete sessionAttributes.currentReservationPrice; - delete sessionAttributes.currentReservation; - sessionAttributes.lastConfirmedReservation = reservation; - callback(close(sessionAttributes, 'Fulfilled', - { contentType: 'PlainText', content: 'Thanks, I have placed your reservation.' })); -} - - // --------------- Intents ----------------------- - -/** - * Called when the user specifies an intent for this skill. - */ -function dispatch(intentRequest, callback) { - console.log(`dispatch userId=${intentRequest.userId}, intentName=${intentRequest.currentIntent.name}`); - - const intentName = intentRequest.currentIntent.name; - - // Dispatch to your skill's intent handlers - if (intentName === 'BookHotel') { - return bookHotel(intentRequest, callback); - } else if (intentName === 'BookCar') { - return bookCar(intentRequest, callback); - } - throw new Error(`Intent with name ${intentName} not supported`); -} - -// --------------- Main handler ----------------------- - -// Route the incoming request based on intent. -// The JSON body of the request is provided in the event slot. -exports.handler = (event, context, callback) => { - try { - console.log(`event.bot.name=${event.bot.name}`); - - /** - * Uncomment this if statement and populate with your Lex bot name, alias and / or version as - * a sanity check to prevent invoking this Lambda function from an undesired source. - */ - /* - if (event.bot.name != 'BookTrip') { - callback('Invalid Bot Name'); - } - */ - dispatch(event, (response) => callback(null, response)); - } catch (err) { - callback(err); - } -}; diff --git a/examples/apps/lex-book-trip/license.txt b/examples/apps/lex-book-trip/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lex-book-trip/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lex-book-trip/readme b/examples/apps/lex-book-trip/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lex-book-trip/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lex-book-trip/requirements.txt b/examples/apps/lex-book-trip/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/lex-book-trip/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/lex-book-trip/template.yaml b/examples/apps/lex-book-trip/template.yaml deleted file mode 100644 index f9834ce818..0000000000 --- a/examples/apps/lex-book-trip/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Book details of a visit, using Amazon Lex to perform natural language - understanding -Parameters: - KeyIdParameter: - Type: String -Resources: - lexbooktrip: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Book details of a visit, using Amazon Lex to perform natural language - understanding - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/lex-make-appointment-python/lambda_function.py b/examples/apps/lex-make-appointment-python/lambda_function.py deleted file mode 100644 index a803f93e38..0000000000 --- a/examples/apps/lex-make-appointment-python/lambda_function.py +++ /dev/null @@ -1,508 +0,0 @@ -""" - This code sample demonstrates an implementation of the Lex Code Hook Interface - in order to serve a bot which manages dentist appointments. - Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console - as part of the 'MakeAppointment' template. - - For instructions on how to set up and test this bot, as well as additional samples, - visit the Lex Getting Started documentation http://docs.aws.amazon.com/lex/latest/dg/getting-started.html. -""" - -import json -import dateutil.parser -import datetime -import math -import random -import logging - -logger = logging.getLogger() -logger.setLevel(logging.DEBUG) - - -""" --- Helpers to build responses which match the structure of the necessary dialog actions --- """ - - -def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message, response_card): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'ElicitSlot', - 'intentName': intent_name, - 'slots': slots, - 'slotToElicit': slot_to_elicit, - 'message': message, - 'responseCard': response_card - } - } - - -def confirm_intent(session_attributes, intent_name, slots, message, response_card): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'ConfirmIntent', - 'intentName': intent_name, - 'slots': slots, - 'message': message, - 'responseCard': response_card - } - } - - -def close(session_attributes, fulfillment_state, message): - response = { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'Close', - 'fulfillmentState': fulfillment_state, - 'message': message - } - } - - return response - - -def delegate(session_attributes, slots): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'Delegate', - 'slots': slots - } - } - - -def build_response_card(title, subtitle, options): - """ - Build a responseCard with a title, subtitle, and an optional set of options which should be displayed as buttons. - """ - buttons = None - if options is not None: - buttons = [] - for i in range(min(5, len(options))): - buttons.append(options[i]) - - return { - 'contentType': 'application/vnd.amazonaws.card.generic', - 'version': 1, - 'genericAttachments': [{ - 'title': title, - 'subTitle': subtitle, - 'buttons': buttons - }] - } - - -""" --- Helper Functions --- """ - - -def parse_int(n): - try: - return int(n) - except ValueError: - return float('nan') - - -def try_ex(func): - """ - Call passed in function in try block. If KeyError is encountered return None. - This function is intended to be used to safely access dictionary. - - Note that this function would have negative impact on performance. - """ - - try: - return func() - except KeyError: - return None - - -def increment_time_by_thirty_mins(time): - hour, minute = map(int, time.split(':')) - return '{}:00'.format(hour + 1) if minute == 30 else '{}:30'.format(hour) - - -def get_random_int(minimum, maximum): - """ - Returns a random integer between min (included) and max (excluded) - """ - min_int = math.ceil(minimum) - max_int = math.floor(maximum) - - return random.randint(min_int, max_int - 1) - - -def get_availabilities(date): - """ - Helper function which in a full implementation would feed into a backend API to provide query schedule availability. - The output of this function is an array of 30 minute periods of availability, expressed in ISO-8601 time format. - - In order to enable quick demonstration of all possible conversation paths supported in this example, the function - returns a mixture of fixed and randomized results. - - On Mondays, availability is randomized; otherwise there is no availability on Tuesday / Thursday and availability at - 10:00 - 10:30 and 4:00 - 5:00 on Wednesday / Friday. - """ - day_of_week = dateutil.parser.parse(date).weekday() - availabilities = [] - available_probability = 0.3 - if day_of_week == 0: - start_hour = 10 - while start_hour <= 16: - if random.random() < available_probability: - # Add an availability window for the given hour, with duration determined by another random number. - appointment_type = get_random_int(1, 4) - if appointment_type == 1: - availabilities.append('{}:00'.format(start_hour)) - elif appointment_type == 2: - availabilities.append('{}:30'.format(start_hour)) - else: - availabilities.append('{}:00'.format(start_hour)) - availabilities.append('{}:30'.format(start_hour)) - start_hour += 1 - - if day_of_week == 2 or day_of_week == 4: - availabilities.append('10:00') - availabilities.append('16:00') - availabilities.append('16:30') - - return availabilities - - -def is_available(time, duration, availabilities): - """ - Helper function to check if the given time and duration fits within a known set of availability windows. - Duration is assumed to be one of 30, 60 (meaning minutes). Availabilities is expected to contain entries of the format HH:MM. - """ - if duration == 30: - return time in availabilities - elif duration == 60: - second_half_hour_time = increment_time_by_thirty_mins(time) - return time in availabilities and second_half_hour_time in availabilities - - # Invalid duration ; throw error. We should not have reached this branch due to earlier validation. - raise Exception('Was not able to understand duration {}'.format(duration)) - - -def get_duration(appointment_type): - appointment_duration_map = {'cleaning': 30, 'root canal': 60, 'whitening': 30} - return try_ex(lambda: appointment_duration_map[appointment_type]) - - -def get_availabilities_for_duration(duration, availabilities): - """ - Helper function to return the windows of availability of the given duration, when provided a set of 30 minute windows. - """ - duration_availabilities = [] - start_time = '10:00' - while start_time != '17:00': - if start_time in availabilities: - if duration == 30: - duration_availabilities.append(start_time) - elif increment_time_by_thirty_mins(start_time) in availabilities: - duration_availabilities.append(start_time) - - start_time = increment_time_by_thirty_mins(start_time) - - return duration_availabilities - - -def build_validation_result(is_valid, violated_slot, message_content): - return { - 'isValid': is_valid, - 'violatedSlot': violated_slot, - 'message': {'contentType': 'PlainText', 'content': message_content} - } - - -def validate_book_appointment(appointment_type, date, time): - if appointment_type and not get_duration(appointment_type): - return build_validation_result(False, 'AppointmentType', 'I did not recognize that, can I book you a root canal, cleaning, or whitening?') - - if time: - if len(time) != 5: - return build_validation_result(False, 'Time', 'I did not recognize that, what time would you like to book your appointment?') - - hour, minute = time.split(':') - hour = parse_int(hour) - minute = parse_int(minute) - if math.isnan(hour) or math.isnan(minute): - return build_validation_result(False, 'Time', 'I did not recognize that, what time would you like to book your appointment?') - - if hour < 10 or hour > 16: - # Outside of business hours - return build_validation_result(False, 'Time', 'Our business hours are ten a.m. to five p.m. What time works best for you?') - - if minute not in [30, 0]: - # Must be booked on the hour or half hour - return build_validation_result(False, 'Time', 'We schedule appointments every half hour, what time works best for you?') - - if date: - if dateutil.parser.parse(date) < datetime.datetime.today(): - return build_validation_result(False, 'Date', 'Your appointment date is in the past! Can you try a different date?') - elif dateutil.parser.parse(date).weekday() == 5 or dateutil.parser.parse(date).weekday() == 6: - return build_validation_result(False, 'Date', 'Our office is not open on the weekends, can you provide a work day?') - - return build_validation_result(True, None, None) - - -def build_time_output_string(time): - hour, minute = time.split(':') # no conversion to int in order to have original string form. for eg) 10:00 instead of 10:0 - if int(hour) > 12: - return '{}:{} p.m.'.format((int(hour) - 12), minute) - elif int(hour) == 12: - return '12:{} p.m.'.format(minute) - elif int(hour) == 0: - return '12:{} a.m.'.format(minute) - - return '{}:{} a.m.'.format(hour, minute) - - -def build_available_time_string(availabilities): - """ - Build a string eliciting for a possible time slot among at least two availabilities. - """ - prefix = 'We have availabilities at ' - if len(availabilities) > 3: - prefix = 'We have plenty of availability, including ' - - prefix += build_time_output_string(availabilities[0]) - if len(availabilities) == 2: - return '{} and {}'.format(prefix, build_time_output_string(availabilities[1])) - - return '{}, {} and {}'.format(prefix, build_time_output_string(availabilities[1]), build_time_output_string(availabilities[2])) - - -def build_options(slot, appointment_type, date, booking_map): - """ - Build a list of potential options for a given slot, to be used in responseCard generation. - """ - day_strings = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] - if slot == 'AppointmentType': - return [ - {'text': 'cleaning (30 min)', 'value': 'cleaning'}, - {'text': 'root canal (60 min)', 'value': 'root canal'}, - {'text': 'whitening (30 min)', 'value': 'whitening'} - ] - elif slot == 'Date': - # Return the next five weekdays. - options = [] - potential_date = datetime.datetime.today() - while len(options) < 5: - potential_date = potential_date + datetime.timedelta(days=1) - if potential_date.weekday() < 5: - options.append({'text': '{}-{} ({})'.format((potential_date.month), potential_date.day, day_strings[potential_date.weekday()]), - 'value': potential_date.strftime('%A, %B %d, %Y')}) - return options - elif slot == 'Time': - # Return the availabilities on the given date. - if not appointment_type or not date: - return None - - availabilities = try_ex(lambda: booking_map[date]) - if not availabilities: - return None - - availabilities = get_availabilities_for_duration(get_duration(appointment_type), availabilities) - if len(availabilities) == 0: - return None - - options = [] - for i in range(min(len(availabilities), 5)): - options.append({'text': build_time_output_string(availabilities[i]), 'value': build_time_output_string(availabilities[i])}) - - return options - - -""" --- Functions that control the bot's behavior --- """ - - -def make_appointment(intent_request): - """ - Performs dialog management and fulfillment for booking a dentists appointment. - - Beyond fulfillment, the implementation for this intent demonstrates the following: - 1) Use of elicitSlot in slot validation and re-prompting - 2) Use of confirmIntent to support the confirmation of inferred slot values, when confirmation is required - on the bot model and the inferred slot values fully specify the intent. - """ - appointment_type = intent_request['currentIntent']['slots']['AppointmentType'] - date = intent_request['currentIntent']['slots']['Date'] - time = intent_request['currentIntent']['slots']['Time'] - source = intent_request['invocationSource'] - output_session_attributes = intent_request['sessionAttributes'] - booking_map = json.loads(try_ex(lambda: output_session_attributes['bookingMap']) or '{}') - - if source == 'DialogCodeHook': - # Perform basic validation on the supplied input slots. - slots = intent_request['currentIntent']['slots'] - validation_result = validate_book_appointment(appointment_type, date, time) - if not validation_result['isValid']: - slots[validation_result['violatedSlot']] = None - return elicit_slot( - output_session_attributes, - intent_request['currentIntent']['name'], - slots, - validation_result['violatedSlot'], - validation_result['message'], - build_response_card( - 'Specify {}'.format(validation_result['violatedSlot']), - validation_result['message']['content'], - build_options(validation_result['violatedSlot'], appointment_type, date, booking_map) - ) - ) - - if not appointment_type: - return elicit_slot( - output_session_attributes, - intent_request['currentIntent']['name'], - intent_request['currentIntent']['slots'], - 'AppointmentType', - {'contentType': 'PlainText', 'content': 'What type of appointment would you like to schedule?'}, - build_response_card( - 'Specify Appointment Type', 'What type of appointment would you like to schedule?', - build_options('AppointmentType', appointment_type, date, None) - ) - ) - - if appointment_type and not date: - return elicit_slot( - output_session_attributes, - intent_request['currentIntent']['name'], - intent_request['currentIntent']['slots'], - 'Date', - {'contentType': 'PlainText', 'content': 'When would you like to schedule your {}?'.format(appointment_type)}, - build_response_card( - 'Specify Date', - 'When would you like to schedule your {}?'.format(appointment_type), - build_options('Date', appointment_type, date, None) - ) - ) - - if appointment_type and date: - # Fetch or generate the availabilities for the given date. - booking_availabilities = try_ex(lambda: booking_map[date]) - if booking_availabilities is None: - booking_availabilities = get_availabilities(date) - booking_map[date] = booking_availabilities - output_session_attributes['bookingMap'] = json.dumps(booking_map) - - appointment_type_availabilities = get_availabilities_for_duration(get_duration(appointment_type), booking_availabilities) - if len(appointment_type_availabilities) == 0: - # No availability on this day at all; ask for a new date and time. - slots['Date'] = None - slots['Time'] = None - return elicit_slot( - output_session_attributes, - intent_request['currentIntent']['name'], - slots, - 'Date', - {'contentType': 'PlainText', 'content': 'We do not have any availability on that date, is there another day which works for you?'}, - build_response_card( - 'Specify Date', - 'What day works best for you?', - build_options('Date', appointment_type, date, booking_map) - ) - ) - - message_content = 'What time on {} works for you? '.format(date) - if time: - output_session_attributes['formattedTime'] = build_time_output_string(time) - # Validate that proposed time for the appointment can be booked by first fetching the availabilities for the given day. To - # give consistent behavior in the sample, this is stored in sessionAttributes after the first lookup. - if is_available(time, get_duration(appointment_type), booking_availabilities): - return delegate(output_session_attributes, slots) - message_content = 'The time you requested is not available. ' - - if len(appointment_type_availabilities) == 1: - # If there is only one availability on the given date, try to confirm it. - slots['Time'] = appointment_type_availabilities[0] - return confirm_intent( - output_session_attributes, - intent_request['currentIntent']['name'], - slots, - { - 'contentType': 'PlainText', - 'content': '{}{} is our only availability, does that work for you?'.format - (message_content, build_time_output_string(appointment_type_availabilities[0])) - }, - build_response_card( - 'Confirm Appointment', - 'Is {} on {} okay?'.format(build_time_output_string(appointment_type_availabilities[0]), date), - [{'text': 'yes', 'value': 'yes'}, {'text': 'no', 'value': 'no'}] - ) - ) - - available_time_string = build_available_time_string(appointment_type_availabilities) - return elicit_slot( - output_session_attributes, - intent_request['currentIntent']['name'], - slots, - 'Time', - {'contentType': 'PlainText', 'content': '{}{}'.format(message_content, available_time_string)}, - build_response_card( - 'Specify Time', - 'What time works best for you?', - build_options('Time', appointment_type, date, booking_map) - ) - ) - - return delegate(output_session_attributes, slots) - - # Book the appointment. In a real bot, this would likely involve a call to a backend service. - duration = get_duration(appointment_type) - booking_availabilities = booking_map[date] - if booking_availabilities: - # Remove the availability slot for the given date as it has now been booked. - booking_availabilities.remove(time) - if duration == 60: - second_half_hour_time = increment_time_by_thirty_mins(time) - booking_availabilities.remove(second_half_hour_time) - - booking_map[date] = booking_availabilities - output_session_attributes['bookingMap'] = json.dumps(booking_map) - else: - # This is not treated as an error as this code sample supports functionality either as fulfillment or dialog code hook. - logger.debug('Availabilities for {} were null at fulfillment time. ' - 'This should have been initialized if this function was configured as the dialog code hook'.format(date)) - - return close( - output_session_attributes, - 'Fulfilled', - { - 'contentType': 'PlainText', - 'content': 'Okay, I have booked your appointment. We will see you at {} on {}'.format(build_time_output_string(time), date) - } - ) - - -""" --- Intents --- """ - - -def dispatch(intent_request): - """ - Called when the user specifies an intent for this bot. - """ - - logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name'])) - - intent_name = intent_request['currentIntent']['name'] - - # Dispatch to your bot's intent handlers - if intent_name == 'MakeAppointment': - return make_appointment(intent_request) - raise Exception('Intent with name ' + intent_name + ' not supported') - - -""" --- Main handler --- """ - - -def lambda_handler(event, context): - """ - Route the incoming request based on intent. - The JSON body of the request is provided in the event slot. - """ - - logger.debug('event.bot.name={}'.format(event['bot']['name'])) - - return dispatch(event) diff --git a/examples/apps/lex-make-appointment-python/license.txt b/examples/apps/lex-make-appointment-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lex-make-appointment-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lex-make-appointment-python/readme b/examples/apps/lex-make-appointment-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lex-make-appointment-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lex-make-appointment-python/requirements.txt b/examples/apps/lex-make-appointment-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/lex-make-appointment-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/lex-make-appointment-python/template.yaml b/examples/apps/lex-make-appointment-python/template.yaml deleted file mode 100644 index f8d04f2fb8..0000000000 --- a/examples/apps/lex-make-appointment-python/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Schedule a dentist appointment, using Amazon Lex to perform natural language - understanding -Parameters: - KeyIdParameter: - Type: String -Resources: - lexmakeappointmentpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - Schedule a dentist appointment, using Amazon Lex to perform natural - language understanding - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/lex-make-appointment/index.js b/examples/apps/lex-make-appointment/index.js deleted file mode 100644 index e6a650f372..0000000000 --- a/examples/apps/lex-make-appointment/index.js +++ /dev/null @@ -1,446 +0,0 @@ -'use strict'; - -/** - * This code sample demonstrates an implementation of the Lex Code Hook Interface - * in order to serve a bot which manages dentist appointments. - * Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console - * as part of the 'MakeAppointment' template. - * - * For instructions on how to set up and test this bot, as well as additional samples, - * visit the Lex Getting Started documentation. - */ - - -// --------------- Helpers to build responses which match the structure of the necessary dialog actions ----------------------- - -function elicitSlot(sessionAttributes, intentName, slots, slotToElicit, message, responseCard) { - return { - sessionAttributes, - dialogAction: { - type: 'ElicitSlot', - intentName, - slots, - slotToElicit, - message, - responseCard, - }, - }; -} - -function confirmIntent(sessionAttributes, intentName, slots, message, responseCard) { - return { - sessionAttributes, - dialogAction: { - type: 'ConfirmIntent', - intentName, - slots, - message, - responseCard, - }, - }; -} - -function close(sessionAttributes, fulfillmentState, message, responseCard) { - return { - sessionAttributes, - dialogAction: { - type: 'Close', - fulfillmentState, - message, - responseCard, - }, - }; -} - -function delegate(sessionAttributes, slots) { - return { - sessionAttributes, - dialogAction: { - type: 'Delegate', - slots, - }, - }; -} - -// Build a responseCard with a title, subtitle, and an optional set of options which should be displayed as buttons. -function buildResponseCard(title, subTitle, options) { - let buttons = null; - if (options != null) { - buttons = []; - for (let i = 0; i < Math.min(5, options.length); i++) { - buttons.push(options[i]); - } - } - return { - contentType: 'application/vnd.amazonaws.card.generic', - version: 1, - genericAttachments: [{ - title, - subTitle, - buttons, - }], - }; -} - -// ---------------- Helper Functions -------------------------------------------------- - -function incrementTimeByThirtyMins(time) { - if (time.length !== 5) { - // Not a valid time - } - const hour = parseInt(time.substring(0, 2), 10); - const minute = parseInt(time.substring(3), 10); - return (minute === 30) ? `${hour + 1}:00` : `${hour}:30`; -} - -// Returns a random integer between min (included) and max (excluded) -function getRandomInt(min, max) { - const minInt = Math.ceil(min); - const maxInt = Math.floor(max); - return Math.floor(Math.random() * (maxInt - minInt)) + minInt; -} - -/** - * Helper function which in a full implementation would feed into a backend API to provide query schedule availability. - * The output of this function is an array of 30 minute periods of availability, expressed in ISO-8601 time format. - * - * In order to enable quick demonstration of all possible conversation paths supported in this example, the function - * returns a mixture of fixed and randomized results. - * - * On Mondays, availability is randomized; otherwise there is no availability on Tuesday / Thursday and availability at - * 10:00 - 10:30 and 4:00 - 5:00 on Wednesday / Friday. - */ -function getAvailabilities(date) { - const dayOfWeek = new Date(date).getDay(); - const availabilities = []; - const availableProbability = 0.3; - if (dayOfWeek === 1) { - let startHour = 10; - while (startHour <= 16) { - if (Math.random() < availableProbability) { - // Add an availability window for the given hour, with duration determined by another random number. - const appointmentType = getRandomInt(1, 4); - if (appointmentType === 1) { - availabilities.push(`${startHour}:00`); - } else if (appointmentType === 2) { - availabilities.push(`${startHour}:30`); - } else { - availabilities.push(`${startHour}:00`); - availabilities.push(`${startHour}:30`); - } - } - startHour++; - } - } - if (dayOfWeek === 3 || dayOfWeek === 5) { - availabilities.push('10:00'); - availabilities.push('16:00'); - availabilities.push('16:30'); - } - return availabilities; -} - -// Helper function to check if the given time and duration fits within a known set of availability windows. -// Duration is assumed to be one of 30, 60 (meaning minutes). Availabilities is expected to contain entries of the format HH:MM. -function isAvailable(time, duration, availabilities) { - if (duration === 30) { - return (availabilities.indexOf(time) !== -1); - } else if (duration === 60) { - const secondHalfHourTime = incrementTimeByThirtyMins(time); - return (availabilities.indexOf(time) !== -1 && availabilities.indexOf(secondHalfHourTime) !== -1); - } - // Invalid duration ; throw error. We should not have reached this branch due to earlier validation. - throw new Error(`Was not able to understand duration ${duration}`); -} - -function getDuration(appointmentType) { - const appointmentDurationMap = { cleaning: 30, 'root canal': 60, whitening: 30 }; - return appointmentDurationMap[appointmentType]; -} - -// Helper function to return the windows of availability of the given duration, when provided a set of 30 minute windows. -function getAvailabilitiesForDuration(duration, availabilities) { - const durationAvailabilities = []; - let startTime = '10:00'; - while (startTime !== '17:00') { - if (availabilities.indexOf(startTime) !== -1) { - if (duration === 30) { - durationAvailabilities.push(startTime); - } else if (availabilities.indexOf(incrementTimeByThirtyMins(startTime)) !== -1) { - durationAvailabilities.push(startTime); - } - } - startTime = incrementTimeByThirtyMins(startTime); - } - return durationAvailabilities; -} - -function buildValidationResult(isValid, violatedSlot, messageContent) { - return { - isValid, - violatedSlot, - message: { contentType: 'PlainText', content: messageContent }, - }; -} - -function validateBookAppointment(appointmentType, date, time) { - if (appointmentType && !getDuration(appointmentType)) { - return buildValidationResult(false, 'AppointmentType', 'I did not recognize that, can I book you a root canal, cleaning, or whitening?'); - } - if (time) { - if (time.length !== 5) { - return buildValidationResult(false, 'Time', 'I did not recognize that, what time would you like to book your appointment?'); - } - const hour = parseInt(time.substring(0, 2), 10); - const minute = parseInt(time.substring(3), 10); - if (isNaN(hour) || isNaN(minute)) { - return buildValidationResult(false, 'Time', 'I did not recognize that, what time would you like to book your appointment?'); - } - if (hour < 10 || hour > 16) { - // Outside of business hours - return buildValidationResult(false, 'Time', 'Our business hours are ten a.m. to five p.m. What time works best for you?'); - } - if ([30, 0].indexOf(minute) === -1) { - // Must be booked on the hour or half hour - return buildValidationResult(false, 'Time', 'We schedule appointments every half hour, what time works best for you?'); - } - } - if (date) { - if (new Date(date) < new Date()) { - return buildValidationResult(false, 'Date', 'Your appointment date is in the past! Can you try a different date?'); - } else if (new Date(date).getDay() === 0 || new Date(date).getDay() === 6) { - return buildValidationResult(false, 'Date', 'Our office is not open on the weekends, can you provide a work day?'); - } - } - return buildValidationResult(true, null, null); -} - -function buildTimeOutputString(time) { - const hour = parseInt(time.substring(0, 2), 10); - const minute = time.substring(3); - if (hour > 12) { - return `${hour - 12}:${minute} p.m.`; - } else if (hour === 12) { - return `12:${minute} p.m.`; - } else if (hour === 0) { - return `12:${minute} a.m.`; - } - return `${hour}:${minute} a.m.`; -} - -// Build a string eliciting for a possible time slot among at least two availabilities. -function buildAvailableTimeString(availabilities) { - let prefix = 'We have availabilities at '; - if (availabilities.length > 3) { - prefix = 'We have plenty of availability, including '; - } - prefix += buildTimeOutputString(availabilities[0]); - if (availabilities.length === 2) { - return `${prefix} and ${buildTimeOutputString(availabilities[1])}`; - } - return `${prefix}, ${buildTimeOutputString(availabilities[1])} and ${buildTimeOutputString(availabilities[2])}`; -} - -// Build a list of potential options for a given slot, to be used in responseCard generation. -function buildOptions(slot, appointmentType, date, bookingMap) { - const dayStrings = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat']; - if (slot === 'AppointmentType') { - return [ - { text: 'cleaning (30 min)', value: 'cleaning' }, - { text: 'root canal (60 min)', value: 'root canal' }, - { text: 'whitening (30 min)', value: 'whitening' }, - ]; - } else if (slot === 'Date') { - // Return the next five weekdays. - const options = []; - const potentialDate = new Date(); - while (options.length < 5) { - potentialDate.setDate(potentialDate.getDate() + 1); - if (potentialDate.getDay() > 0 && potentialDate.getDay() < 6) { - options.push({ text: `${potentialDate.getMonth() + 1}-${potentialDate.getDate()} (${dayStrings[potentialDate.getDay()]})`, - value: potentialDate.toDateString() }); - } - } - return options; - } else if (slot === 'Time') { - // Return the availabilities on the given date. - if (!appointmentType || !date) { - return null; - } - let availabilities = bookingMap[`${date}`]; - if (!availabilities) { - return null; - } - availabilities = getAvailabilitiesForDuration(getDuration(appointmentType), availabilities); - if (availabilities.length === 0) { - return null; - } - const options = []; - for (let i = 0; i < Math.min(availabilities.length, 5); i++) { - options.push({ text: buildTimeOutputString(availabilities[i]), value: buildTimeOutputString(availabilities[i]) }); - } - return options; - } -} - - // --------------- Functions that control the skill's behavior ----------------------- - -/** - * Performs dialog management and fulfillment for booking a dentists appointment. - * - * Beyond fulfillment, the implementation for this intent demonstrates the following: - * 1) Use of elicitSlot in slot validation and re-prompting - * 2) Use of confirmIntent to support the confirmation of inferred slot values, when confirmation is required - * on the bot model and the inferred slot values fully specify the intent. - */ -function makeAppointment(intentRequest, callback) { - const appointmentType = intentRequest.currentIntent.slots.AppointmentType; - const date = intentRequest.currentIntent.slots.Date; - const time = intentRequest.currentIntent.slots.Time; - const source = intentRequest.invocationSource; - const outputSessionAttributes = intentRequest.sessionAttributes; - const bookingMap = JSON.parse(outputSessionAttributes.bookingMap || '{}'); - - if (source === 'DialogCodeHook') { - // Perform basic validation on the supplied input slots. - const slots = intentRequest.currentIntent.slots; - const validationResult = validateBookAppointment(appointmentType, date, time); - if (!validationResult.isValid) { - slots[`${validationResult.violatedSlot}`] = null; - callback(elicitSlot(outputSessionAttributes, intentRequest.currentIntent.name, - slots, validationResult.violatedSlot, validationResult.message, - buildResponseCard(`Specify ${validationResult.violatedSlot}`, validationResult.message.content, - buildOptions(validationResult.violatedSlot, appointmentType, date, bookingMap)))); - return; - } - - if (!appointmentType) { - callback(elicitSlot(outputSessionAttributes, intentRequest.currentIntent.name, - intentRequest.currentIntent.slots, 'AppointmentType', - { contentType: 'PlainText', content: 'What type of appointment would you like to schedule?' }, - buildResponseCard('Specify Appointment Type', 'What type of appointment would you like to schedule?', - buildOptions('AppointmentType', appointmentType, date, null)))); - return; - } - if (appointmentType && !date) { - callback(elicitSlot(outputSessionAttributes, intentRequest.currentIntent.name, - intentRequest.currentIntent.slots, 'Date', - { contentType: 'PlainText', content: `When would you like to schedule your ${appointmentType}?` }, - buildResponseCard('Specify Date', `When would you like to schedule your ${appointmentType}?`, - buildOptions('Date', appointmentType, date, null)))); - return; - } - - if (appointmentType && date) { - // Fetch or generate the availabilities for the given date. - let bookingAvailabilities = bookingMap[`${date}`]; - if (bookingAvailabilities == null) { - bookingAvailabilities = getAvailabilities(date); - bookingMap[`${date}`] = bookingAvailabilities; - outputSessionAttributes.bookingMap = JSON.stringify(bookingMap); - } - - const appointmentTypeAvailabilities = getAvailabilitiesForDuration(getDuration(appointmentType), bookingAvailabilities); - if (appointmentTypeAvailabilities.length === 0) { - //No availability on this day at all; ask for a new date and time. - slots.Date = null; - slots.Time = null; - callback(elicitSlot(outputSessionAttributes, intentRequest.currentIntent.name, slots, 'Date', - { contentType: 'PlainText', content: 'We do not have any availability on that date, is there another day which works for you?' }, - buildResponseCard('Specify Date', 'What day works best for you?', - buildOptions('Date', appointmentType, date, bookingMap)))); - return; - } - let messageContent = `What time on ${date} works for you? `; - if (time) { - outputSessionAttributes.formattedTime = buildTimeOutputString(time); - // Validate that proposed time for the appointment can be booked by first fetching the availabilities for the given day. To - // give consistent behavior in the sample, this is stored in sessionAttributes after the first lookup. - if (isAvailable(time, getDuration(appointmentType), bookingAvailabilities)) { - callback(delegate(outputSessionAttributes, slots)); - return; - } - messageContent = 'The time you requested is not available. '; - } - if (appointmentTypeAvailabilities.length === 1) { - // If there is only one availability on the given date, try to confirm it. - slots.Time = appointmentTypeAvailabilities[0]; - callback(confirmIntent(outputSessionAttributes, intentRequest.currentIntent.name, slots, - { contentType: 'PlainText', content: `${messageContent}${buildTimeOutputString(appointmentTypeAvailabilities[0])} is our only availability, does that work for you?` }, - buildResponseCard('Confirm Appointment', `Is ${buildTimeOutputString(appointmentTypeAvailabilities[0])} on ${date} okay?`, - [{ text: 'yes', value: 'yes' }, { text: 'no', value: 'no' }]))); - return; - } - const availableTimeString = buildAvailableTimeString(appointmentTypeAvailabilities); - callback(elicitSlot(outputSessionAttributes, intentRequest.currentIntent.name, slots, 'Time', - { contentType: 'PlainText', content: `${messageContent}${availableTimeString}` }, - buildResponseCard('Specify Time', 'What time works best for you?', - buildOptions('Time', appointmentType, date, bookingMap)))); - return; - } - - callback(delegate(outputSessionAttributes, slots)); - return; - } - - // Book the appointment. In a real bot, this would likely involve a call to a backend service. - const duration = getDuration(appointmentType); - const bookingAvailabilities = bookingMap[`${date}`]; - if (bookingAvailabilities) { - // Remove the availability slot for the given date as it has now been booked. - bookingAvailabilities.splice(bookingAvailabilities.indexOf(time), 1); - if (duration === 60) { - const secondHalfHourTime = incrementTimeByThirtyMins(time); - bookingAvailabilities.splice(bookingAvailabilities.indexOf(secondHalfHourTime), 1); - } - bookingMap[`${date}`] = bookingAvailabilities; - outputSessionAttributes.bookingMap = JSON.stringify(bookingMap); - } else { - // This is not treated as an error as this code sample supports functionality either as fulfillment or dialog code hook. - console.log(`Availabilities for ${date} were null at fulfillment time. This should have been initialized if this function was configured as the dialog code hook`); - } - - callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText', - content: `Okay, I have booked your appointment. We will see you at ${buildTimeOutputString(time)} on ${date}` })); -} - - // --------------- Intents ----------------------- - -/** - * Called when the user specifies an intent for this skill. - */ -function dispatch(intentRequest, callback) { - console.log(`dispatch userId=${intentRequest.userId}, intent=${intentRequest.currentIntent.name}`); - - const name = intentRequest.currentIntent.name; - - // Dispatch to your skill's intent handlers - if (name === 'MakeAppointment') { - return makeAppointment(intentRequest, callback); - } - throw new Error(`Intent with name ${name} not supported`); -} - -// --------------- Main handler ----------------------- - -// Route the incoming request based on intent. -// The JSON body of the request is provided in the event slot. -exports.handler = (event, context, callback) => { - try { - console.log(`event.bot.name=${event.bot.name}`); - - /** - * Uncomment this if statement and populate with your Lex bot name and / or version as - * a sanity check to prevent invoking this Lambda function from an undesired Lex bot or - * bot version. - */ - /* - if (event.bot.name !== 'MakeAppointment') { - callback('Invalid Bot Name'); - } - */ - dispatch(event, (response) => callback(null, response)); - } catch (err) { - callback(err); - } -}; diff --git a/examples/apps/lex-make-appointment/license.txt b/examples/apps/lex-make-appointment/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lex-make-appointment/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lex-make-appointment/readme b/examples/apps/lex-make-appointment/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lex-make-appointment/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lex-make-appointment/template.yaml b/examples/apps/lex-make-appointment/template.yaml deleted file mode 100644 index cadf65258b..0000000000 --- a/examples/apps/lex-make-appointment/template.yaml +++ /dev/null @@ -1,23 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Schedule a dentist appointment, using Amazon Lex to perform natural language - understanding -Parameters: - KeyIdParameter: - Type: String -Resources: - lexmakeappointment: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Schedule a dentist appointment, using Amazon Lex to perform natural - language understanding - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/lex-order-flowers-python/lambda_function.py b/examples/apps/lex-order-flowers-python/lambda_function.py deleted file mode 100644 index 5f36fd5499..0000000000 --- a/examples/apps/lex-order-flowers-python/lambda_function.py +++ /dev/null @@ -1,191 +0,0 @@ -""" -This sample demonstrates an implementation of the Lex Code Hook Interface -in order to serve a sample bot which manages orders for flowers. -Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console -as part of the 'OrderFlowers' template. - -For instructions on how to set up and test this bot, as well as additional samples, -visit the Lex Getting Started documentation http://docs.aws.amazon.com/lex/latest/dg/getting-started.html. -""" -import math -import datetime -import logging - -logger = logging.getLogger() -logger.setLevel(logging.DEBUG) - - -""" --- Helpers to build responses which match the structure of the necessary dialog actions --- """ - - -def get_slots(intent_request): - return intent_request['currentIntent']['slots'] - - -def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'ElicitSlot', - 'intentName': intent_name, - 'slots': slots, - 'slotToElicit': slot_to_elicit, - 'message': message - } - } - - -def close(session_attributes, fulfillment_state, message): - response = { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'Close', - 'fulfillmentState': fulfillment_state, - 'message': message - } - } - - return response - - -def delegate(session_attributes, slots): - return { - 'sessionAttributes': session_attributes, - 'dialogAction': { - 'type': 'Delegate', - 'slots': slots - } - } - - -""" --- Helper Functions --- """ - - -def parse_int(n): - try: - return int(n) - except ValueError: - return float('nan') - - -def build_validation_result(is_valid, violated_slot, message_content): - if message_content is None: - return { - "isValid": is_valid, - "violatedSlot": violated_slot, - } - - return { - 'isValid': is_valid, - 'violatedSlot': violated_slot, - 'message': {'contentType': 'PlainText', 'content': message_content} - } - - -def validate_order_flowers(flower_type, date, time): - flower_types = ['lilies', 'roses', 'tulips'] - if flower_type is not None and flower_type not in flower_types: - return build_validation_result(False, - 'FlowerType', - 'We do not have {}, would you like a different type of flower? ' - 'Our most popular flowers are roses'.format(flower_type)) - - if date is not None: - if datetime.datetime.strptime(date, '%Y-%m-%d').date() < datetime.date.today(): - return build_validation_result(False, 'PickupDate', 'Your pickup date is in the past! Can you try a different date?') - - if time is not None: - if len(time) != 5: - # Not a valid time; use a prompt defined on the build-time model. - return build_validation_result(False, 'PickupTime', None) - - hour, minute = time.split(':') - hour = parse_int(hour) - minute = parse_int(minute) - if math.isnan(hour) or math.isnan(minute): - # Not a valid time; use a prompt defined on the build-time model. - return build_validation_result(False, 'PickupTime', None) - - if hour < 10 or hour > 16: - # Outside of business hours - return build_validation_result(False, 'PickupTime', 'Our business hours are from ten a m. to five p m. Can you specify a time during this range?') - - return build_validation_result(True, None, None) - - -""" --- Functions that control the bot's behavior --- """ - - -def order_flowers(intent_request): - """ - Performs dialog management and fulfillment for ordering flowers. - Beyond fulfillment, the implementation of this intent demonstrates the use of the elicitSlot dialog action - in slot validation and re-prompting. - """ - - flower_type = get_slots(intent_request)["FlowerType"] - date = get_slots(intent_request)["PickupDate"] - time = get_slots(intent_request)["PickupTime"] - source = intent_request['invocationSource'] - - if source == 'DialogCodeHook': - # Perform basic validation on the supplied input slots. - # Use the elicitSlot dialog action to re-prompt for the first violation detected. - slots = get_slots(intent_request) - - validation_result = validate_order_flowers(flower_type, date, time) - if not validation_result['isValid']: - slots[validation_result['violatedSlot']] = None - return elicit_slot(intent_request['sessionAttributes'], - intent_request['currentIntent']['name'], - slots, - validation_result['violatedSlot'], - validation_result['message']) - - # Pass the price of the flowers back through session attributes to be used in various prompts defined - # on the bot model. - output_session_attributes = intent_request['sessionAttributes'] - if flower_type is not None: - output_session_attributes['Price'] = len(flower_type) * 5 # Elegant pricing model - - return delegate(output_session_attributes, get_slots(intent_request)) - - # Order the flowers, and rely on the goodbye message of the bot to define the message to the end user. - # In a real bot, this would likely involve a call to a backend service. - return close(intent_request['sessionAttributes'], - 'Fulfilled', - {'contentType': 'PlainText', - 'content': 'Thanks, your order for {} has been placed and will be ready for pickup by {} on {}'.format(flower_type, time, date)}) - - -""" --- Intents --- """ - - -def dispatch(intent_request): - """ - Called when the user specifies an intent for this bot. - """ - - logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name'])) - - intent_name = intent_request['currentIntent']['name'] - - # Dispatch to your bot's intent handlers - if intent_name == 'OrderFlowers': - return order_flowers(intent_request) - - raise Exception('Intent with name ' + intent_name + ' not supported') - - -""" --- Main handler --- """ - - -def lambda_handler(event, context): - """ - Route the incoming request based on intent. - The JSON body of the request is provided in the event slot. - """ - - logger.debug('event.bot.name={}'.format(event['bot']['name'])) - - return dispatch(event) diff --git a/examples/apps/lex-order-flowers-python/license.txt b/examples/apps/lex-order-flowers-python/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lex-order-flowers-python/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lex-order-flowers-python/readme b/examples/apps/lex-order-flowers-python/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lex-order-flowers-python/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lex-order-flowers-python/requirements.txt b/examples/apps/lex-order-flowers-python/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/lex-order-flowers-python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/lex-order-flowers-python/template.yaml b/examples/apps/lex-order-flowers-python/template.yaml deleted file mode 100644 index 79b5ec064a..0000000000 --- a/examples/apps/lex-order-flowers-python/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Order flowers, using Amazon Lex to perform natural language understanding' -Parameters: - KeyIdParameter: - Type: String -Resources: - lexorderflowerspython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - Order flowers, using Amazon Lex to perform natural language - understanding - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/lex-order-flowers/index.js b/examples/apps/lex-order-flowers/index.js deleted file mode 100644 index b824f3b7e8..0000000000 --- a/examples/apps/lex-order-flowers/index.js +++ /dev/null @@ -1,173 +0,0 @@ -'use strict'; - - /** - * This sample demonstrates an implementation of the Lex Code Hook Interface - * in order to serve a sample bot which manages orders for flowers. - * Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console - * as part of the 'OrderFlowers' template. - * - * For instructions on how to set up and test this bot, as well as additional samples, - * visit the Lex Getting Started documentation. - */ - - - // --------------- Helpers to build responses which match the structure of the necessary dialog actions ----------------------- - -function elicitSlot(sessionAttributes, intentName, slots, slotToElicit, message) { - return { - sessionAttributes, - dialogAction: { - type: 'ElicitSlot', - intentName, - slots, - slotToElicit, - message, - }, - }; -} - -function close(sessionAttributes, fulfillmentState, message) { - return { - sessionAttributes, - dialogAction: { - type: 'Close', - fulfillmentState, - message, - }, - }; -} - -function delegate(sessionAttributes, slots) { - return { - sessionAttributes, - dialogAction: { - type: 'Delegate', - slots, - }, - }; -} - -// ---------------- Helper Functions -------------------------------------------------- - -function buildValidationResult(isValid, violatedSlot, messageContent) { - if (messageContent == null) { - return { - isValid, - violatedSlot, - }; - } - return { - isValid, - violatedSlot, - message: { contentType: 'PlainText', content: messageContent }, - }; -} - -function validateOrderFlowers(flowerType, date, time) { - const flowerTypes = ['lilies', 'roses', 'tulips']; - if (flowerType && flowerTypes.indexOf(flowerType) === -1) { - return buildValidationResult(false, 'FlowerType', `We do not have ${flowerType}, would you like a different type of flower? Our most popular flowers are roses`); - } - if (date) { - if (new Date(date) < new Date()) { - return buildValidationResult(false, 'PickupDate', 'Your pickup date is in the past! Can you try a different date?'); - } - } - if (time) { - if (time.length !== 5) { - // Not a valid time; use a prompt defined on the build-time model. - return buildValidationResult(false, 'PickupTime', null); - } - const hour = parseInt(time.substring(0, 2), 10); - const minute = parseInt(time.substring(3), 10); - if (isNaN(hour) || isNaN(minute)) { - // Not a valid time; use a prompt defined on the build-time model. - return buildValidationResult(false, 'PickupTime', null); - } - if (hour < 10 || hour > 16) { - // Outside of business hours - return buildValidationResult(false, 'PickupTime', 'Our business hours are from ten a m. to five p m. Can you specify a time during this range?'); - } - } - return buildValidationResult(true, null, null); -} - - // --------------- Functions that control the bot's behavior ----------------------- - -/** - * Performs dialog management and fulfillment for ordering flowers. - * - * Beyond fulfillment, the implementation of this intent demonstrates the use of the elicitSlot dialog action - * in slot validation and re-prompting. - * - */ -function orderFlowers(intentRequest, callback) { - const flowerType = intentRequest.currentIntent.slots.FlowerType; - const date = intentRequest.currentIntent.slots.PickupDate; - const time = intentRequest.currentIntent.slots.PickupTime; - const source = intentRequest.invocationSource; - - if (source === 'DialogCodeHook') { - // Perform basic validation on the supplied input slots. Use the elicitSlot dialog action to re-prompt for the first violation detected. - const slots = intentRequest.currentIntent.slots; - const validationResult = validateOrderFlowers(flowerType, date, time); - if (!validationResult.isValid) { - slots[`${validationResult.violatedSlot}`] = null; - callback(elicitSlot(intentRequest.sessionAttributes, intentRequest.currentIntent.name, slots, validationResult.violatedSlot, validationResult.message)); - return; - } - - // Pass the price of the flowers back through session attributes to be used in various prompts defined on the bot model. - const outputSessionAttributes = intentRequest.sessionAttributes; - if (flowerType) { - outputSessionAttributes.Price = flowerType.length * 5; // Elegant pricing model - } - callback(delegate(outputSessionAttributes, intentRequest.currentIntent.slots)); - return; - } - - // Order the flowers, and rely on the goodbye message of the bot to define the message to the end user. In a real bot, this would likely involve a call to a backend service. - callback(close(intentRequest.sessionAttributes, 'Fulfilled', - { contentType: 'PlainText', content: `Thanks, your order for ${flowerType} has been placed and will be ready for pickup by ${time} on ${date}` })); -} - - // --------------- Intents ----------------------- - -/** - * Called when the user specifies an intent for this skill. - */ -function dispatch(intentRequest, callback) { - console.log(`dispatch userId=${intentRequest.userId}, intentName=${intentRequest.currentIntent.name}`); - - const intentName = intentRequest.currentIntent.name; - - // Dispatch to your skill's intent handlers - if (intentName === 'OrderFlowers') { - return orderFlowers(intentRequest, callback); - } - throw new Error(`Intent with name ${intentName} not supported`); -} - -// --------------- Main handler ----------------------- - -// Route the incoming request based on intent. -// The JSON body of the request is provided in the event slot. -exports.handler = (event, context, callback) => { - try { - console.log(`event.bot.name=${event.bot.name}`); - - /** - * Uncomment this if statement and populate with your Lex bot name and / or version as - * a sanity check to prevent invoking this Lambda function from an undesired Lex bot or - * bot version. - */ - /* - if (event.bot.name !== 'OrderFlowers') { - callback('Invalid Bot Name'); - } - */ - dispatch(event, (response) => callback(null, response)); - } catch (err) { - callback(err); - } -}; diff --git a/examples/apps/lex-order-flowers/license.txt b/examples/apps/lex-order-flowers/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/lex-order-flowers/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/lex-order-flowers/readme b/examples/apps/lex-order-flowers/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/lex-order-flowers/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/lex-order-flowers/template.yaml b/examples/apps/lex-order-flowers/template.yaml deleted file mode 100644 index d4faeb7bc0..0000000000 --- a/examples/apps/lex-order-flowers/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: 'Order flowers, using Amazon Lex to perform natural language understanding' -Parameters: - KeyIdParameter: - Type: String -Resources: - lexorderflowers: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Order flowers, using Amazon Lex to perform natural language - understanding - MemorySize: 128 - Timeout: 10 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter \ No newline at end of file diff --git a/examples/apps/logicmonitor-send-cloudwatch-events/readme b/examples/apps/logicmonitor-send-cloudwatch-events/readme deleted file mode 100644 index ba4b2bc2ab..0000000000 --- a/examples/apps/logicmonitor-send-cloudwatch-events/readme +++ /dev/null @@ -1,3 +0,0 @@ -CloudWatch Events has been re-launched as Amazon EventBridge with full backwards compatibility - -Please see ../logicmonitor-send-eventbridge-events/ for the migrated code \ No newline at end of file diff --git a/examples/apps/logicmonitor-send-eventbridge-events/lambda_function.py b/examples/apps/logicmonitor-send-eventbridge-events/lambda_function.py deleted file mode 100644 index 9ac8d9c75d..0000000000 --- a/examples/apps/logicmonitor-send-eventbridge-events/lambda_function.py +++ /dev/null @@ -1,213 +0,0 @@ -''' -This function uses the LogicMonitor REST API to create LogicMonitor OpsNotes -for EventBridge Events. -Once the Ops Notes have been created for monitored resources that have -associated events, you'll see them on all graphs for those resources. -Assuming you already have monitored AWS resources in LogicMonitor, you'll -need to perform the following steps: - -Follow these steps to provision LogicMonitor API Tokens as environment -variables for the Lambda Function: - - 1. Navigate to https://.logicmonitor.com. - - 2. Locate the Users & Roles section within the Settings Page. - - 3. Identify an existing user or create a new existing user with - permission to manage all devices. As a best practice, we recommend - creating a designated API user for the integration. - - 4. Create a set of API Tokens from the Manage User dialog for the - user in step 3. Copy the Access Id and Access Key values for use - n the next section. - - -To add your LogicMonitor API Tokens as environment variables, follow these -steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste the value of the Access Id in the API_ACCESS_ID environment - variable and click encrypt. - - 4. Paste the value of the Access Key in the API_ACCESS_KEY environment - variable and click encrypt. - - 5. Provide your LogicMonitor account name as the value of the - ACCOUNT_NAME environment variable and click encrypt. - - -Follow these steps to configure EventBridge Rules that will trigger -the Lambda Function: - - 1. Create an EventBridge Rule that matches the events you'd like - to show up in your LogicMonitor account - https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html - - 2. Configure the rule to trigger this Lambda Function. - - -This code requires the upload of a zip to include the "requests" library. -Do no edit this in the lambda UI. -''' - -from __future__ import print_function - -import requests -import os -import hashlib -import base64 -import time -import hmac -import json -import boto3 -from base64 import b64decode - -from six import string_types - -print('Loading function') - - -# Use LogicMonitor's API to search for a monitored device given an ARN -def find_device_by_arn(args): - device_info = lm_api("GET", "", "/device/devices", - "?filter=systemProperties.value:{}".format( - args['arn']), - args['account_name'], args['api_access_id'], - args['api_access_key']) - if len(device_info['data']['items']) == 1: - return device_info['data']['items'][0] - else: - return None - - -# Add a LogicMonitor OpsNote to a particular device, given the deviceId -# and the note / tags that should be included -def add_opsNote(args, device): - data = {"scopes": [{"type": "device", "deviceId": device['id']}], - "note": '{}: {}'.format(args['tag'], args['note']), - "tags": [{"name": args['tag']}]} - opsNote_response = lm_api("POST", json.dumps(data), "/setting/opsnotes", - "", args['account_name'], args['api_access_id'], - args['api_access_key']) - return opsNote_response - - -# Generic helper fuction to abstract the interation with the LM API -# Handles generation of authentication header string and -# interfacing with the HTTPs endpoint -def lm_api(verb, data, resource, query, account_name, access_id, access_key): - # generic definition for all lm RESTful resources - url = ('https://{}.logicmonitor.com/santaba/rest{}{}'.format(account_name, - resource, - query)) - - # Lets set the epoch so that it doesn't change between the - # two locations we need to use it - epoch = str(int(time.time() * 1000)) - - # Time to start building the auth strings for our headers - auth_contents = verb + epoch + data + resource - digest = hmac.new(access_key, msg=auth_contents, - digestmod=hashlib.sha256).hexdigest() - signature = base64.b64encode(digest) - auth = 'LMv1 {}:{}:{}'.format(access_id, signature, epoch) - - # Abstract the calling of the http verb as we are already defining - # it above. Make sure that we insert the customer Auth header - response = getattr(requests, verb.lower())(url, - data=data, - headers={'Content-Type': - 'application/json', - 'Authorization': auth}) - - # In the case that we have a 200 response we should have a - # json response content. However let's verify to make sure - if (response.status_code is requests.codes.ok and - response.headers['Content-Type'] == "application/json"): - return response.json() - else: - # Raise exception for bad status - response.raise_for_status() - # Return response content in the case of good status but - # bad response header - return response.text - - -# Decrypt value using KMS -def decrypt(text): - kms = boto3.client("kms") - response = kms.decrypt(CiphertextBlob=b64decode(text)) - return response["Plaintext"] - - -# Main event function -def lambda_handler(event, context): - # Get LogicMonitor API keys / account name from environment variables, - # where API keys are encrypted - args = {} - args['account_name'] = os.environ["ACCOUNT_NAME"] - encrypted_id = os.environ["API_ACCESS_ID"] - encrypted_key = os.environ["API_ACCESS_KEY"] - - # Decrypt LM API keys - args['api_access_id'] = decrypt(encrypted_id) - args['api_access_key'] = decrypt(encrypted_key).replace("'", "") - - # Define the OpsNote message content to the event detail object - args['note'] = json.dumps(event['detail'], indent=4) - - # Define OpsNote tag as the type of event - args['tag'] = event['detail-type'] - - # For every resource listed for the event, identify the ARN, search - # LogicMonitor using that ARN and add OpsNotes to any identified devices - for resource in event['resources']: - # Set ARN - args['arn'] = resource - # Search for LM devices by ARN - device = find_device_by_arn(args) - # If a device was found, add an OpsNote - if device: - print("Found device:") - print(device) - resp = add_opsNote(args, device) - print("Added Ops Note:") - print(resp) - - # Log note if a device was found for at least one ARN - # in the event resources - if device: - print("Found at least one device and added Ops Notes") - return resp - - # If no devices matched an ARN for the event resources, - # look for devices matching ARNs in event details - else: - print("Could not find any devices with resource ARN " + - args['arn'] + "- checking event details...") - # Identify ARN in event detail - for key, value in event['detail'].iteritems(): - if isinstance(value, string_types): - if 'arn' in value: - args['arn'] = value - # Search for LM devices based on identified ARN - print("Found arn: {} - checking devices...".format( - args['arn'])) - device = find_device_by_arn(args) - # If a device is found, add an OpsNote - if device: - print("Found device:") - print(device) - resp = add_opsNote(args, device) - print("Added Ops Note:") - print(resp) - return resp - # If no devices are found, note that no monitored devices matched - # the ARNs recorded for the event - print("Could not find any devices with ARNs in event detail") - print("Exiting") - return diff --git a/examples/apps/logicmonitor-send-eventbridge-events/license.txt b/examples/apps/logicmonitor-send-eventbridge-events/license.txt deleted file mode 100644 index e987a5544a..0000000000 --- a/examples/apps/logicmonitor-send-eventbridge-events/license.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 LogicMonitor - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/examples/apps/logicmonitor-send-eventbridge-events/readme b/examples/apps/logicmonitor-send-eventbridge-events/readme deleted file mode 100644 index 8609b15dc1..0000000000 --- a/examples/apps/logicmonitor-send-eventbridge-events/readme +++ /dev/null @@ -1,38 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' \ No newline at end of file diff --git a/examples/apps/logicmonitor-send-eventbridge-events/requirements.txt b/examples/apps/logicmonitor-send-eventbridge-events/requirements.txt deleted file mode 100644 index 6f5275b1c5..0000000000 --- a/examples/apps/logicmonitor-send-eventbridge-events/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.13.0 diff --git a/examples/apps/logicmonitor-send-eventbridge-events/template.yaml b/examples/apps/logicmonitor-send-eventbridge-events/template.yaml deleted file mode 100644 index 3090373faf..0000000000 --- a/examples/apps/logicmonitor-send-eventbridge-events/template.yaml +++ /dev/null @@ -1,28 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Creates LogicMonitor OpsNotes for EventBridge Events, thereby enabling - correlation between events and performance data. -Parameters: - KeyIdParameter: - Type: String -Resources: - logicmonitorsendeventbridgeevents: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - Creates LogicMonitor OpsNotes for EventBridge Events, thereby enabling - correlation between events and performance data. - MemorySize: 128 - Timeout: 30 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Environment: - Variables: - ACCOUNT_NAME: - API_ACCESS_ID: - API_ACCESS_KEY: diff --git a/examples/apps/microservice-http-endpoint-python/lambda_function.py b/examples/apps/microservice-http-endpoint-python/lambda_function.py deleted file mode 100644 index 6eb3dc3fc5..0000000000 --- a/examples/apps/microservice-http-endpoint-python/lambda_function.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import print_function - -import boto3 -import json - -print('Loading function') -dynamo = boto3.client('dynamodb') - - -def respond(err, res=None): - return { - 'statusCode': '400' if err else '200', - 'body': err.message if err else json.dumps(res), - 'headers': { - 'Content-Type': 'application/json', - }, - } - - -def lambda_handler(event, context): - '''Demonstrates a simple HTTP endpoint using API Gateway. You have full - access to the request and response payload, including headers and - status code. - - To scan a DynamoDB table, make a GET request with the TableName as a - query string parameter. To put, update, or delete an item, make a POST, - PUT, or DELETE request respectively, passing in the payload to the - DynamoDB API as a JSON body. - ''' - #print("Received event: " + json.dumps(event, indent=2)) - - operations = { - 'DELETE': lambda dynamo, x: dynamo.delete_item(**x), - 'GET': lambda dynamo, x: dynamo.scan(**x), - 'POST': lambda dynamo, x: dynamo.put_item(**x), - 'PUT': lambda dynamo, x: dynamo.update_item(**x), - } - - operation = event['httpMethod'] - if operation in operations: - payload = event['queryStringParameters'] if operation == 'GET' else json.loads(event['body']) - return respond(None, operations[operation](dynamo, payload)) - else: - return respond(ValueError('Unsupported method "{}"'.format(operation))) diff --git a/examples/apps/microservice-http-endpoint-python/template.yaml b/examples/apps/microservice-http-endpoint-python/template.yaml deleted file mode 100644 index 805c74ddcf..0000000000 --- a/examples/apps/microservice-http-endpoint-python/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway. -Parameters: - TableNameParameter: - Type: String -Resources: - microservicehttpendpointpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - A simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway. - MemorySize: 512 - Timeout: 10 - Policies: - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY diff --git a/examples/apps/microservice-http-endpoint-python3/lambda_function.py b/examples/apps/microservice-http-endpoint-python3/lambda_function.py deleted file mode 100644 index b00a29872e..0000000000 --- a/examples/apps/microservice-http-endpoint-python3/lambda_function.py +++ /dev/null @@ -1,46 +0,0 @@ - -import boto3 -import json -import os - -print('Loading function') -dynamo = boto3.client('dynamodb') -table_name = os.environ['TABLE_NAME'] - - -def respond(err, res=None): - return { - 'statusCode': '400' if err else '200', - 'body': err.message if err else json.dumps(res), - 'headers': { - 'Content-Type': 'application/json', - }, - } - - -def lambda_handler(event, context): - '''Demonstrates a simple HTTP endpoint using API Gateway. You have full - access to the request and response payload, including headers and - status code. - - TableName provided by template.yaml. - - To scan a DynamoDB table, make a GET request with optional query string parameter. - To put, update, or delete an item, make a POST, PUT, or DELETE request respectively, - passing in the payload to the DynamoDB API as a JSON body. - ''' - print("Received event: " + json.dumps(event, indent=2)) - - operations = { - 'DELETE': lambda dynamo, x: dynamo.delete_item(TableName=table_name, **x), - 'GET': lambda dynamo, x: dynamo.scan(TableName=table_name, **x) if x else dynamo.scan(TableName=table_name), - 'POST': lambda dynamo, x: dynamo.put_item(TableName=table_name, **x), - 'PUT': lambda dynamo, x: dynamo.update_item(TableName=table_name, **x), - } - - operation = event['httpMethod'] - if operation in operations: - payload = event['queryStringParameters'] if operation == 'GET' else json.loads(event['body']) - return respond(None, operations[operation](dynamo, payload)) - else: - return respond(ValueError('Unsupported method "{}"'.format(operation))) diff --git a/examples/apps/microservice-http-endpoint-python3/template.yaml b/examples/apps/microservice-http-endpoint-python3/template.yaml deleted file mode 100644 index 2e10b5c97a..0000000000 --- a/examples/apps/microservice-http-endpoint-python3/template.yaml +++ /dev/null @@ -1,40 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway. - -Parameters: - TableNameParameter: - Type: String - -Globals: - #https://github.com/awslabs/serverless-application-model/blob/develop/docs/globals.rst - Function: - Runtime: python3.6 - MemorySize: 512 - Environment: - Variables: - TABLE_NAME: - Ref: Table - -Resources: - microservicehttpendpointpython3: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - CodeUri: . - Description: >- - A simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway. - Timeout: 10 - Policies: - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY - - Table: - Type: AWS::Serverless::SimpleTable diff --git a/examples/apps/microservice-http-endpoint-python3/test-output.log b/examples/apps/microservice-http-endpoint-python3/test-output.log deleted file mode 100644 index c155553494..0000000000 --- a/examples/apps/microservice-http-endpoint-python3/test-output.log +++ /dev/null @@ -1,70 +0,0 @@ -❯ ./test.sh https://vxldx8ck9i.execute-api.us-west-2.amazonaws.com/Prod/MyResource ./test-payload.json -+ http POST https://vxldx8ck9i.execute-api.us-west-2.amazonaws.com/Prod/MyResource Item:=@./test-payload.json -HTTP/1.1 200 OK -Connection: keep-alive -Content-Length: 414 -Content-Type: application/json -Date: Thu, 03 May 2018 21:13:56 GMT -Via: 1.1 d159f3d447f69796b1a04dffe8d243c0.cloudfront.net (CloudFront) -X-Amz-Cf-Id: 60kAxGheadAiJo-ksjknQr-rAh-WZ2EaJXMT_cYH5nzgwIudXHUu9g== -X-Amzn-Trace-Id: Root=1-5aeb7b94-457eb371f443bfc06c5dadb3 -X-Cache: Miss from cloudfront -x-amz-apigw-id: GVA_OEZIPHcFleg= -x-amzn-RequestId: e3e943ab-4f16-11e8-af74-e7a92312c1b8 - -{ - "ResponseMetadata": { - "HTTPHeaders": { - "connection": "keep-alive", - "content-length": "2", - "content-type": "application/x-amz-json-1.0", - "date": "Thu, 03 May 2018 21:13:56 GMT", - "server": "Server", - "x-amz-crc32": "2745614147", - "x-amzn-requestid": "VQGS8JQIH2G9CDO8P65U6HMKEFVV4KQNSO5AEMVJF66Q9ASUAAJG" - }, - "HTTPStatusCode": 200, - "RequestId": "VQGS8JQIH2G9CDO8P65U6HMKEFVV4KQNSO5AEMVJF66Q9ASUAAJG", - "RetryAttempts": 0 - } -} - -+ http GET https://vxldx8ck9i.execute-api.us-west-2.amazonaws.com/Prod/MyResource -HTTP/1.1 200 OK -Connection: keep-alive -Content-Length: 485 -Content-Type: application/json -Date: Thu, 03 May 2018 21:13:57 GMT -Via: 1.1 0419e0c9f6ea9a42ab82db8feb536aee.cloudfront.net (CloudFront) -X-Amz-Cf-Id: Nsflnq2N-dxYOskE8ui1ULydLO9fg7-HaCmbtjMwZ1A7Pr_wgEJUhA== -X-Amzn-Trace-Id: Root=1-5aeb7b95-f0ceaed903bf48b8605b6899 -X-Cache: Miss from cloudfront -x-amz-apigw-id: GVA_UHO5PHcFo7w= -x-amzn-RequestId: e444d07b-4f16-11e8-8db6-6940d66a847c - -{ - "Count": 1, - "Items": [ - { - "id": { - "S": "id_string" - } - } - ], - "ResponseMetadata": { - "HTTPHeaders": { - "connection": "keep-alive", - "content-length": "63", - "content-type": "application/x-amz-json-1.0", - "date": "Thu, 03 May 2018 21:13:57 GMT", - "server": "Server", - "x-amz-crc32": "3041197985", - "x-amzn-requestid": "9NFOFDHCCR5OE0V81IUC70Q6FNVV4KQNSO5AEMVJF66Q9ASUAAJG" - }, - "HTTPStatusCode": 200, - "RequestId": "9NFOFDHCCR5OE0V81IUC70Q6FNVV4KQNSO5AEMVJF66Q9ASUAAJG", - "RetryAttempts": 0 - }, - "ScannedCount": 1 -} - diff --git a/examples/apps/microservice-http-endpoint-python3/test-payload.json b/examples/apps/microservice-http-endpoint-python3/test-payload.json deleted file mode 100644 index 01908265f6..0000000000 --- a/examples/apps/microservice-http-endpoint-python3/test-payload.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": { - "S": "id_string" - } -} diff --git a/examples/apps/microservice-http-endpoint-python3/test.sh b/examples/apps/microservice-http-endpoint-python3/test.sh deleted file mode 100755 index 96caa92b6b..0000000000 --- a/examples/apps/microservice-http-endpoint-python3/test.sh +++ /dev/null @@ -1,19 +0,0 @@ -#/bin/bash -e - -# Test invocation using httpie (http) in place of curl for syntax simplicity -# -# Args: $1: API GW path -# $2 json payload data file -# -# eg: ./test.sh https://.execute-api..amazonaws.com/Prod/MyResource ./test-payload.json - -set -x - -# Write one item - -http POST $1 Item:=@$2 - -# Read all back - -http GET $1 - diff --git a/examples/apps/microservice-http-endpoint/index.js b/examples/apps/microservice-http-endpoint/index.js deleted file mode 100644 index 4d3c25ed2a..0000000000 --- a/examples/apps/microservice-http-endpoint/index.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -const doc = require('dynamodb-doc'); - -const dynamo = new doc.DynamoDB(); - - -/** - * Demonstrates a simple HTTP endpoint using API Gateway. You have full - * access to the request and response payload, including headers and - * status code. - * - * To scan a DynamoDB table, make a GET request with the TableName as a - * query string parameter. To put, update, or delete an item, make a POST, - * PUT, or DELETE request respectively, passing in the payload to the - * DynamoDB API as a JSON body. - */ -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - - const done = (err, res) => callback(null, { - statusCode: err ? '400' : '200', - body: err ? err.message : JSON.stringify(res), - headers: { - 'Content-Type': 'application/json', - }, - }); - - switch (event.httpMethod) { - case 'DELETE': - dynamo.deleteItem(JSON.parse(event.body), done); - break; - case 'GET': - dynamo.scan({ TableName: event.queryStringParameters.TableName }, done); - break; - case 'POST': - dynamo.putItem(JSON.parse(event.body), done); - break; - case 'PUT': - dynamo.updateItem(JSON.parse(event.body), done); - break; - default: - done(new Error(`Unsupported method "${event.httpMethod}"`)); - } -}; diff --git a/examples/apps/microservice-http-endpoint/package.json b/examples/apps/microservice-http-endpoint/package.json deleted file mode 100644 index 348d78f270..0000000000 --- a/examples/apps/microservice-http-endpoint/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "nodejs-upgrade-functions", - "version": "1.0.0", - "private": true, - "dependencies": { - "throat": "^4.0.0" - } -} diff --git a/examples/apps/microservice-http-endpoint/template.yaml b/examples/apps/microservice-http-endpoint/template.yaml deleted file mode 100644 index 986be557d0..0000000000 --- a/examples/apps/microservice-http-endpoint/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway. -Parameters: - TableNameParameter: - Type: String -Resources: - microservicehttpendpoint: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - A simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway. - MemorySize: 512 - Timeout: 10 - Policies: - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY \ No newline at end of file diff --git a/examples/apps/node-exec/index.js b/examples/apps/node-exec/index.js deleted file mode 100644 index 062a0cbaf5..0000000000 --- a/examples/apps/node-exec/index.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -const exec = require('child_process').exec; - -exports.handler = (event, context, callback) => { - if (!event.cmd) { - return callback('Please specify a command to run as event.cmd'); - } - const child = exec(event.cmd, (error) => { - // Resolve with result of process - callback(error, 'Process complete!'); - }); - - // Log process stdout and stderr - child.stdout.on('data', console.log); - child.stderr.on('data', console.error); -}; diff --git a/examples/apps/node-exec/lambda_function.py b/examples/apps/node-exec/lambda_function.py deleted file mode 100644 index e2fd2cf90e..0000000000 --- a/examples/apps/node-exec/lambda_function.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import print_function - -import boto3 -from decimal import Decimal -import json -import urllib - -print('Loading function') - -rekognition = boto3.client('rekognition') - - -# --------------- Helper Functions to call Rekognition APIs ------------------ - - -def detect_faces(bucket, key): - response = rekognition.detect_faces(Image={"S3Object": {"Bucket": bucket, "Name": key}}) - return response - - -def detect_labels(bucket, key): - response = rekognition.detect_labels(Image={"S3Object": {"Bucket": bucket, "Name": key}}) - - # Sample code to write response to DynamoDB table 'MyTable' with 'PK' as Primary Key. - # Note: role used for executing this Lambda function should have write access to the table. - #table = boto3.resource('dynamodb').Table('MyTable') - #labels = [{'Confidence': Decimal(str(label_prediction['Confidence'])), 'Name': label_prediction['Name']} for label_prediction in response['Labels']] - #table.put_item(Item={'PK': key, 'Labels': labels}) - return response - - -def index_faces(bucket, key): - # Note: Collection has to be created upfront. Use CreateCollection API to create a collecion. - #rekognition.create_collection(CollectionId='BLUEPRINT_COLLECTION') - response = rekognition.index_faces(Image={"S3Object": {"Bucket": bucket, "Name": key}}, CollectionId="BLUEPRINT_COLLECTION") - return response - - -# --------------- Main handler ------------------ - - -def lambda_handler(event, context): - '''Demonstrates S3 trigger that uses - Rekognition APIs to detect faces, labels and index faces in S3 Object. - ''' - #print("Received event: " + json.dumps(event, indent=2)) - - # Get the object from the event - bucket = event['Records'][0]['s3']['bucket']['name'] - key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8')) - try: - # Calls rekognition DetectFaces API to detect faces in S3 object - response = detect_faces(bucket, key) - - # Calls rekognition DetectLabels API to detect labels in S3 object - #response = detect_labels(bucket, key) - - # Calls rekognition IndexFaces API to detect faces in S3 object and index faces into specified collection - #response = index_faces(bucket, key) - - # Print response to console. - print(response) - - return response - except Exception as e: - print(e) - print("Error processing object {} from bucket {}. ".format(key, bucket) + - "Make sure your object and bucket exist and your bucket is in the same region as this function.") - raise e diff --git a/examples/apps/node-exec/response/detect-faces-response.json b/examples/apps/node-exec/response/detect-faces-response.json deleted file mode 100644 index 3287f8388b..0000000000 --- a/examples/apps/node-exec/response/detect-faces-response.json +++ /dev/null @@ -1 +0,0 @@ -{"FaceDetails": [{"BoundingBox": {"Width": 0.37220844626426697, "Top": 0.097087375819683075, "Height": 0.56011950969696045, "Left": 0.60049629211425781}, "Landmarks": [{"Y": 0.29746288061141968, "X": 0.74046933650970459, "Type": "eyeLeft"}, {"Y": 0.39010941982269287, "X": 0.85312539339065552, "Type": "eyeRight"}, {"Y": 0.43307429552078247, "X": 0.80672019720077515, "Type": "nose"}, {"Y": 0.51852452754974365, "X": 0.7020527720451355, "Type": "mouthLeft"}, {"Y": 0.56728619337081909, "X": 0.78770458698272705, "Type": "mouthRight"}], "Pose": {"Yaw": 25.503475189208984, "Roll": 27.584785461425781, "Pitch": 16.070867538452148}, "Quality": {"Sharpness": 140.0, "Brightness": 45.784263610839844}, "Confidence": 99.999870300292969}], "ResponseMetadata": {"RetryAttempts": 0, "HTTPStatusCode": 200, "RequestId": "5ec8d1f8-a853-11e6-ae5a-0f6c6597f701", "HTTPHeaders": {"date": "Fri, 11 Nov 2016 21:11:12 GMT", "x-amzn-requestid": "5ec8d1f8-a853-11e6-ae5a-0f6c6597f701", "content-length": "699", "content-type": "application/x-amz-json-1.1", "connection": "keep-alive"}}, "OrientationCorrection": "ROTATE_0"} diff --git a/examples/apps/node-exec/template.yaml b/examples/apps/node-exec/template.yaml deleted file mode 100644 index 3150c841af..0000000000 --- a/examples/apps/node-exec/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Demonstrates running an external process using the Node.js child_process module. -Parameters: - BucketNameParameter: - Type: String - CollectionIdParameter: - Type: String -Resources: - nodeexec: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Demonstrates running an external process using the Node.js child_process module. - MemorySize: 128 - Timeout: 3 - Policies: - - S3CrudPolicy: - BucketName: !Ref BucketNameParameter - - RekognitionNoDataAccessPolicy: - CollectionId: !Ref CollectionIdParameter - - RekognitionWriteOnlyAccessPolicy: - CollectionId: !Ref CollectionIdParameter \ No newline at end of file diff --git a/examples/apps/node-exec/testEvent.json b/examples/apps/node-exec/testEvent.json deleted file mode 100644 index a3ed7c7b2f..0000000000 --- a/examples/apps/node-exec/testEvent.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "cmd": "pwd" -} diff --git a/examples/apps/rekognition-python/lambda_function.py b/examples/apps/rekognition-python/lambda_function.py deleted file mode 100644 index e2fd2cf90e..0000000000 --- a/examples/apps/rekognition-python/lambda_function.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import print_function - -import boto3 -from decimal import Decimal -import json -import urllib - -print('Loading function') - -rekognition = boto3.client('rekognition') - - -# --------------- Helper Functions to call Rekognition APIs ------------------ - - -def detect_faces(bucket, key): - response = rekognition.detect_faces(Image={"S3Object": {"Bucket": bucket, "Name": key}}) - return response - - -def detect_labels(bucket, key): - response = rekognition.detect_labels(Image={"S3Object": {"Bucket": bucket, "Name": key}}) - - # Sample code to write response to DynamoDB table 'MyTable' with 'PK' as Primary Key. - # Note: role used for executing this Lambda function should have write access to the table. - #table = boto3.resource('dynamodb').Table('MyTable') - #labels = [{'Confidence': Decimal(str(label_prediction['Confidence'])), 'Name': label_prediction['Name']} for label_prediction in response['Labels']] - #table.put_item(Item={'PK': key, 'Labels': labels}) - return response - - -def index_faces(bucket, key): - # Note: Collection has to be created upfront. Use CreateCollection API to create a collecion. - #rekognition.create_collection(CollectionId='BLUEPRINT_COLLECTION') - response = rekognition.index_faces(Image={"S3Object": {"Bucket": bucket, "Name": key}}, CollectionId="BLUEPRINT_COLLECTION") - return response - - -# --------------- Main handler ------------------ - - -def lambda_handler(event, context): - '''Demonstrates S3 trigger that uses - Rekognition APIs to detect faces, labels and index faces in S3 Object. - ''' - #print("Received event: " + json.dumps(event, indent=2)) - - # Get the object from the event - bucket = event['Records'][0]['s3']['bucket']['name'] - key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8')) - try: - # Calls rekognition DetectFaces API to detect faces in S3 object - response = detect_faces(bucket, key) - - # Calls rekognition DetectLabels API to detect labels in S3 object - #response = detect_labels(bucket, key) - - # Calls rekognition IndexFaces API to detect faces in S3 object and index faces into specified collection - #response = index_faces(bucket, key) - - # Print response to console. - print(response) - - return response - except Exception as e: - print(e) - print("Error processing object {} from bucket {}. ".format(key, bucket) + - "Make sure your object and bucket exist and your bucket is in the same region as this function.") - raise e diff --git a/examples/apps/rekognition-python/response/detect-faces-response.json b/examples/apps/rekognition-python/response/detect-faces-response.json deleted file mode 100644 index 3287f8388b..0000000000 --- a/examples/apps/rekognition-python/response/detect-faces-response.json +++ /dev/null @@ -1 +0,0 @@ -{"FaceDetails": [{"BoundingBox": {"Width": 0.37220844626426697, "Top": 0.097087375819683075, "Height": 0.56011950969696045, "Left": 0.60049629211425781}, "Landmarks": [{"Y": 0.29746288061141968, "X": 0.74046933650970459, "Type": "eyeLeft"}, {"Y": 0.39010941982269287, "X": 0.85312539339065552, "Type": "eyeRight"}, {"Y": 0.43307429552078247, "X": 0.80672019720077515, "Type": "nose"}, {"Y": 0.51852452754974365, "X": 0.7020527720451355, "Type": "mouthLeft"}, {"Y": 0.56728619337081909, "X": 0.78770458698272705, "Type": "mouthRight"}], "Pose": {"Yaw": 25.503475189208984, "Roll": 27.584785461425781, "Pitch": 16.070867538452148}, "Quality": {"Sharpness": 140.0, "Brightness": 45.784263610839844}, "Confidence": 99.999870300292969}], "ResponseMetadata": {"RetryAttempts": 0, "HTTPStatusCode": 200, "RequestId": "5ec8d1f8-a853-11e6-ae5a-0f6c6597f701", "HTTPHeaders": {"date": "Fri, 11 Nov 2016 21:11:12 GMT", "x-amzn-requestid": "5ec8d1f8-a853-11e6-ae5a-0f6c6597f701", "content-length": "699", "content-type": "application/x-amz-json-1.1", "connection": "keep-alive"}}, "OrientationCorrection": "ROTATE_0"} diff --git a/examples/apps/rekognition-python/template.yaml b/examples/apps/rekognition-python/template.yaml deleted file mode 100644 index 93e7930c5c..0000000000 --- a/examples/apps/rekognition-python/template.yaml +++ /dev/null @@ -1,38 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon S3 trigger that uses rekognition APIs to detect faces -Parameters: - BucketNamePrefix: - Type: String - Default: sam-example - CollectionIdParameter: - Type: String -Resources: - rekognitionpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: An Amazon S3 trigger that uses rekognition APIs to detect faces - MemorySize: 128 - Timeout: 3 - Policies: - - S3CrudPolicy: - BucketName: !Sub "${BucketNamePrefix}-rekognition" - - RekognitionNoDataAccessPolicy: - CollectionId: !Ref CollectionIdParameter - - RekognitionWriteOnlyAccessPolicy: - CollectionId: !Ref CollectionIdParameter - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: - Ref: Bucket1 - Events: - - 's3:ObjectCreated:*' - Bucket1: - Type: 'AWS::S3::Bucket' - Properties: - BucketName: !Sub "${BucketNamePrefix}-rekognition" diff --git a/examples/apps/s3-get-object-python/lambda_function.py b/examples/apps/s3-get-object-python/lambda_function.py deleted file mode 100644 index 3f22548363..0000000000 --- a/examples/apps/s3-get-object-python/lambda_function.py +++ /dev/null @@ -1,25 +0,0 @@ -from __future__ import print_function - -import json -import urllib -import boto3 - -print('Loading function') - -s3 = boto3.client('s3') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - - # Get the object from the event and show its content type - bucket = event['Records'][0]['s3']['bucket']['name'] - key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'].encode('utf8')) - try: - response = s3.get_object(Bucket=bucket, Key=key) - print("CONTENT TYPE: " + response['ContentType']) - return response['ContentType'] - except Exception as e: - print(e) - print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket)) - raise e diff --git a/examples/apps/s3-get-object-python/template.yaml b/examples/apps/s3-get-object-python/template.yaml deleted file mode 100644 index 7860ececc9..0000000000 --- a/examples/apps/s3-get-object-python/template.yaml +++ /dev/null @@ -1,36 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon S3 trigger that retrieves metadata for the object that has been - updated. -Parameters: - BucketNamePrefix: - Type: String - Default: sam-example -Resources: - s3getobjectpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon S3 trigger that retrieves metadata for the object that has - been updated. - MemorySize: 128 - Timeout: 3 - Policies: - - S3CrudPolicy: - BucketName: !Sub "${BucketNamePrefix}-get-object-python" - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: - Ref: Bucket1 - Events: - - 's3:ObjectCreated:*' - Bucket1: - Type: 'AWS::S3::Bucket' - Properties: - BucketName: !Sub "${BucketNamePrefix}-get-object-python" diff --git a/examples/apps/s3-get-object-python3/index.js b/examples/apps/s3-get-object-python3/index.js deleted file mode 100644 index 995e8c633e..0000000000 --- a/examples/apps/s3-get-object-python3/index.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Stream events from AWS CloudWatch Logs to Splunk - * - * This function streams AWS CloudWatch Logs to Splunk using - * Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to stream logs to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); -const zlib = require('zlib'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - - // CloudWatch Logs data is base64 encoded so decode here - const payload = new Buffer(event.awslogs.data, 'base64'); - // CloudWatch Logs are gzip compressed so expand here - zlib.gunzip(payload, (err, result) => { - if (err) { - callback(err); - } else { - const parsed = JSON.parse(result.toString('ascii')); - console.log('Decoded payload:', JSON.stringify(parsed, null, 2)); - let count = 0; - if (parsed.logEvents) { - parsed.logEvents.forEach((item) => { - /* Log event to Splunk with explicit event timestamp. - - Use optional 'context' argument to send Lambda metadata e.g. awsRequestId, functionName. - - Change "item.timestamp" below if time is specified in another field in the event. - - Change to "logger.log(item.message, context)" if no time field is present in event. */ - logger.logWithTime(item.timestamp, item.message, context); - - /* Alternatively, UNCOMMENT logger call below if you want to override Splunk input settings */ - /* Log event to Splunk with any combination of explicit timestamp, index, source, sourcetype, and host. - - Complete list of input settings available at http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector */ - // logger.logEvent({ - // time: new Date(item.timestamp).getTime() / 1000, - // host: 'serverless', - // source: `lambda:${context.functionName}`, - // sourcetype: 'httpevent', - // index: 'main', - // event: item.message, - // }); - - count += 1; - }); - } - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - console.log(`Successfully processed ${count} log event(s).`); - callback(null, count); // Return number of log events - } - }); - } - }); -}; diff --git a/examples/apps/s3-get-object-python3/lambda_function.py b/examples/apps/s3-get-object-python3/lambda_function.py deleted file mode 100644 index 68b49ffb9a..0000000000 --- a/examples/apps/s3-get-object-python3/lambda_function.py +++ /dev/null @@ -1,24 +0,0 @@ - -import json -import urllib.parse -import boto3 - -print('Loading function') - -s3 = boto3.client('s3') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - - # Get the object from the event and show its content type - bucket = event['Records'][0]['s3']['bucket']['name'] - key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8') - try: - response = s3.get_object(Bucket=bucket, Key=key) - print("CONTENT TYPE: " + response['ContentType']) - return response['ContentType'] - except Exception as e: - print(e) - print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket)) - raise e diff --git a/examples/apps/s3-get-object-python3/lib/mysplunklogger.js b/examples/apps/s3-get-object-python3/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/s3-get-object-python3/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/s3-get-object-python3/template.yaml b/examples/apps/s3-get-object-python3/template.yaml deleted file mode 100644 index 09dcf6218a..0000000000 --- a/examples/apps/s3-get-object-python3/template.yaml +++ /dev/null @@ -1,36 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon S3 trigger that retrieves metadata for the object that has been - updated. -Parameters: - BucketNamePrefix: - Type: String - Default: sam-example -Resources: - s3getobjectpython3: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python3.6 - CodeUri: . - Description: >- - An Amazon S3 trigger that retrieves metadata for the object that has - been updated. - MemorySize: 128 - Timeout: 3 - Policies: - - S3CrudPolicy: - BucketName: !Sub "${BucketNamePrefix}-get-object-python3" - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: - Ref: Bucket1 - Events: - - 's3:ObjectCreated:*' - Bucket1: - Type: 'AWS::S3::Bucket' - Properties: - BucketName: !Sub "${BucketNamePrefix}-get-object-python3" diff --git a/examples/apps/s3-get-object/index.js b/examples/apps/s3-get-object/index.js deleted file mode 100644 index 9263829649..0000000000 --- a/examples/apps/s3-get-object/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -const aws = require('aws-sdk'); - -const s3 = new aws.S3({ apiVersion: '2006-03-01' }); - - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - - // Get the object from the event and show its content type - const bucket = event.Records[0].s3.bucket.name; - const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); - const params = { - Bucket: bucket, - Key: key, - }; - s3.getObject(params, (err, data) => { - if (err) { - console.log(err); - const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; - console.log(message); - callback(message); - } else { - console.log('CONTENT TYPE:', data.ContentType); - callback(null, data.ContentType); - } - }); -}; diff --git a/examples/apps/s3-get-object/template.yaml b/examples/apps/s3-get-object/template.yaml deleted file mode 100644 index 9ab349e875..0000000000 --- a/examples/apps/s3-get-object/template.yaml +++ /dev/null @@ -1,35 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon S3 trigger that retrieves metadata for the object that has been - updated. -Parameters: - BucketNamePrefix: - Type: String - Default: sam-example -Resources: - s3getobject: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon S3 trigger that retrieves metadata for the object that has - been updated. - MemorySize: 128 - Timeout: 3 - Policies: - - S3CrudPolicy: - BucketName: !Sub "${BucketNamePrefix}-get-object" - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: !Ref Bucket1 - Events: - - 's3:ObjectCreated:*' - Bucket1: - Type: 'AWS::S3::Bucket' - Properties: - BucketName: !Sub "${BucketNamePrefix}-get-object" diff --git a/examples/apps/s3-get-object/testEvent.json b/examples/apps/s3-get-object/testEvent.json deleted file mode 100644 index 23ead1551b..0000000000 --- a/examples/apps/s3-get-object/testEvent.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "Records": [ - { - "eventVersion": "2.0", - "eventSource": "aws:s3", - "awsRegion": "us-east-1", - "eventTime": "1970-01-01T00:00:00.000Z", - "eventName": "ObjectCreated:Put", - "userIdentity": { - "principalId": "EXAMPLE" - }, - "requestParameters": { - "sourceIPAddress": "127.0.0.1" - }, - "responseElements": { - "x-amz-request-id": "EXAMPLE123456789", - "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH" - }, - "s3": { - "s3SchemaVersion": "1.0", - "configurationId": "testConfigRule", - "bucket": { - "name": "example-bucket-get-object", - "ownerIdentity": { - "principalId": "EXAMPLE" - }, - "arn": "arn:aws:s3:::example-bucket-get-object" - }, - "object": { - "key": "test/key", - "size": 1024, - "eTag": "0123456789abcdef0123456789abcdef", - "sequencer": "0A1B2C3D4E5F678901" - } - } - } - ] -} diff --git a/examples/apps/ses-notification-nodejs/index.js b/examples/apps/ses-notification-nodejs/index.js deleted file mode 100644 index a625e83896..0000000000 --- a/examples/apps/ses-notification-nodejs/index.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - const message = JSON.parse(event.Records[0].Sns.Message); - - switch(message.notificationType) { - case 'Bounce': - handleBounce(message); - break; - case 'Complaint': - handleComplaint(message); - break; - case 'Delivery': - handleDelivery(message); - break; - default: - callback(`Unknown notification type: ${message.notificationType}`); - } -}; - -function handleBounce(message) { - const messageId = message.mail.messageId; - const addresses = message.bounce.bouncedRecipients.map((recipient) => recipient.emailAddress); - const bounceType = message.bounce.bounceType; - - console.log(`Message ${messageId} bounced when sending to ${addresses.join(', ')}. Bounce type: ${bounceType}`); -} - -function handleComplaint(message) { - const messageId = message.mail.messageId; - const addresses = message.complaint.complainedRecipients.map((recipient) => recipient.emailAddress); - - console.log(`A complaint was reported by ${addresses.join(', ')} for message ${messageId}.`); -} - -function handleDelivery(message) { - const messageId = message.mail.messageId; - const deliveryTimestamp = message.delivery.timestamp; - - console.log(`Message ${messageId} was delivered successfully at ${deliveryTimestamp}.`); -} diff --git a/examples/apps/ses-notification-nodejs/template.yaml b/examples/apps/ses-notification-nodejs/template.yaml deleted file mode 100644 index a8d3f8d8f7..0000000000 --- a/examples/apps/ses-notification-nodejs/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon SES notification handler for processing bounces, complaints and deliveries. -Parameters: - TableNameParameter: - Type: String -Resources: - sesnotificationnodejs: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - An Amazon SES notification handler for processing bounces, complaints and deliveries. - MemorySize: 128 - Timeout: 3 - Policies: - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/ses-notification-python/lambda_function.py b/examples/apps/ses-notification-python/lambda_function.py deleted file mode 100644 index 25a6c7c2af..0000000000 --- a/examples/apps/ses-notification-python/lambda_function.py +++ /dev/null @@ -1,47 +0,0 @@ -from __future__ import print_function -import json - - -def lambda_handler(event, context): - message = json.loads(event['Records'][0]['Sns']['Message']) - notification_type = message['notificationType'] - handlers.get(notification_type, handle_unknown_type)(message) - - -def handle_bounce(message): - message_id = message['mail']['messageId'] - bounced_recipients = message['bounce']['bouncedRecipients'] - addresses = list( - recipient['emailAddress'] for recipient in bounced_recipients - ) - bounce_type = message['bounce']['bounceType'] - print("Message %s bounced when sending to %s. Bounce type: %s" % - (message_id, ", ".join(addresses), bounce_type)) - - -def handle_complaint(message): - message_id = message['mail']['messageId'] - complained_recipients = message['complaint']['complainedRecipients'] - addresses = list( - recipient['emailAddress'] for recipient in complained_recipients - ) - print("A complaint was reported by %s for message %s." % - (", ".join(addresses), message_id)) - - -def handle_delivery(message): - message_id = message['mail']['messageId'] - delivery_timestamp = message['delivery']['timestamp'] - print("Message %s was delivered successfully at %s" % - (message_id, delivery_timestamp)) - - -def handle_unknown_type(message): - print("Unknown message type:\n%s" % json.dumps(message)) - raise Exception("Invalid message type received: %s" % - message['notificationType']) - - -handlers = {"Bounce": handle_bounce, - "Complaint": handle_complaint, - "Delivery": handle_delivery} diff --git a/examples/apps/ses-notification-python/template.yaml b/examples/apps/ses-notification-python/template.yaml deleted file mode 100644 index 70bcd165fb..0000000000 --- a/examples/apps/ses-notification-python/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An Amazon SES notification handler for processing bounces, complaints and deliveries. -Parameters: - TableNameParameter: - Type: String -Resources: - sesnotificationpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An Amazon SES notification handler for processing bounces, complaints and deliveries. - MemorySize: 128 - Timeout: 3 - Policies: - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter \ No newline at end of file diff --git a/examples/apps/simple-mobile-backend/index.js b/examples/apps/simple-mobile-backend/index.js deleted file mode 100644 index 6a800279e6..0000000000 --- a/examples/apps/simple-mobile-backend/index.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -const doc = require('dynamodb-doc'); - -const dynamo = new doc.DynamoDB(); - - -/** - * Provide an event that contains the following keys: - * - * - operation: one of the operations in the switch statement below - * - tableName: required for operations that interact with DynamoDB - * - payload: a parameter to pass to the operation being performed - */ -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - - const operation = event.operation; - const payload = event.payload; - - if (event.tableName) { - payload.TableName = event.tableName; - } - - switch (operation) { - case 'create': - dynamo.putItem(payload, callback); - break; - case 'read': - dynamo.getItem(payload, callback); - break; - case 'update': - dynamo.updateItem(payload, callback); - break; - case 'delete': - dynamo.deleteItem(payload, callback); - break; - case 'list': - dynamo.scan(payload, callback); - break; - case 'echo': - callback(null, payload); - break; - case 'ping': - callback(null, 'pong'); - break; - default: - callback(new Error(`Unrecognized operation "${operation}"`)); - } -}; diff --git a/examples/apps/simple-mobile-backend/template.yaml b/examples/apps/simple-mobile-backend/template.yaml deleted file mode 100644 index a211603ef8..0000000000 --- a/examples/apps/simple-mobile-backend/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: A simple mobile backend (read/write to DynamoDB). -Parameters: - TableNameParameter: - Type: String -Resources: - simplemobilebackend: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: A simple mobile backend (read/write to DynamoDB). - MemorySize: 128 - Timeout: 3 - Policies: - - DynamoDBCrudPolicy: - TableName: !Ref TableNameParameter diff --git a/examples/apps/slack-echo-command-python/lambda_function.py b/examples/apps/slack-echo-command-python/lambda_function.py deleted file mode 100644 index ef604da270..0000000000 --- a/examples/apps/slack-echo-command-python/lambda_function.py +++ /dev/null @@ -1,80 +0,0 @@ -''' -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - -To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -''' - -import boto3 -import json -import logging -import os - -from base64 import b64decode -from urlparse import parse_qs - - -ENCRYPTED_EXPECTED_TOKEN = os.environ['kmsEncryptedToken'] - -kms = boto3.client('kms') -expected_token = kms.decrypt(CiphertextBlob=b64decode(ENCRYPTED_EXPECTED_TOKEN))['Plaintext'] - -logger = logging.getLogger() -logger.setLevel(logging.INFO) - - -def respond(err, res=None): - return { - 'statusCode': '400' if err else '200', - 'body': err.message if err else json.dumps(res), - 'headers': { - 'Content-Type': 'application/json', - }, - } - - -def lambda_handler(event, context): - params = parse_qs(event['body']) - token = params['token'][0] - if token != expected_token: - logger.error("Request token (%s) does not match expected", token) - return respond(Exception('Invalid request token')) - - user = params['user_name'][0] - command = params['command'][0] - channel = params['channel_name'][0] - command_text = params['text'][0] - - return respond(None, "%s invoked %s in %s with the following text: %s" % (user, command, channel, command_text)) diff --git a/examples/apps/slack-echo-command-python/template.yaml b/examples/apps/slack-echo-command-python/template.yaml deleted file mode 100644 index 66b87df721..0000000000 --- a/examples/apps/slack-echo-command-python/template.yaml +++ /dev/null @@ -1,32 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A function that handles a Slack slash command and echoes the details back to - the user. -Parameters: - KeyIdParameter: - Type: String -Resources: - slackechocommandpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - A function that handles a Slack slash command and echoes the details - back to the user. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY - Environment: - Variables: - kmsEncryptedToken: diff --git a/examples/apps/slack-echo-command/index.js b/examples/apps/slack-echo-command/index.js deleted file mode 100644 index 01942303c8..0000000000 --- a/examples/apps/slack-echo-command/index.js +++ /dev/null @@ -1,91 +0,0 @@ -'use strict'; - -/* -This function handles a Slack slash command and echoes the details back to the user. - -Follow these steps to configure the slash command in Slack: - - 1. Navigate to https://.slack.com/services/new - - 2. Search for and select "Slash Commands". - - 3. Enter a name for your command and click "Add Slash Command Integration". - - 4. Copy the token string from the integration settings and use it in the next section. - - 5. After you complete this blueprint, enter the provided API endpoint URL in the URL field. - - - To encrypt your secrets use the following steps: - - 1. Create or use an existing KMS Key - http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html - - 2. Click the "Enable Encryption Helpers" checkbox - - 3. Paste into the kmsEncryptedToken environment variable and click encrypt - -Follow these steps to complete the configuration of your command API endpoint - - 1. When completing the blueprint configuration select "Open" for security - on the "Configure triggers" page. - - 2. Enter a name for your execution role in the "Role name" field. - Your function's execution role needs kms:Decrypt permissions. We have - pre-selected the "KMS decryption permissions" policy template that will - automatically add these permissions. - - 3. Update the URL for your Slack slash command with the invocation URL for the - created API resource in the prod stage. -*/ - -const AWS = require('aws-sdk'); -const qs = require('querystring'); - -const kmsEncryptedToken = process.env.kmsEncryptedToken; -let token; - - -function processEvent(event, callback) { - const params = qs.parse(event.body); - const requestToken = params.token; - if (requestToken !== token) { - console.error(`Request token (${requestToken}) does not match expected`); - return callback('Invalid request token'); - } - - const user = params.user_name; - const command = params.command; - const channel = params.channel_name; - const commandText = params.text; - - callback(null, `${user} invoked ${command} in ${channel} with the following text: ${commandText}`); -} - - -exports.handler = (event, context, callback) => { - const done = (err, res) => callback(null, { - statusCode: err ? '400' : '200', - body: err ? (err.message || err) : JSON.stringify(res), - headers: { - 'Content-Type': 'application/json', - }, - }); - - if (token) { - // Container reuse, simply process the event with the key in memory - processEvent(event, done); - } else if (kmsEncryptedToken && kmsEncryptedToken !== '') { - const cipherText = { CiphertextBlob: new Buffer(kmsEncryptedToken, 'base64') }; - const kms = new AWS.KMS(); - kms.decrypt(cipherText, (err, data) => { - if (err) { - console.log('Decrypt error:', err); - return done(err); - } - token = data.Plaintext.toString('ascii'); - processEvent(event, done); - }); - } else { - done('Token has not been set.'); - } -}; diff --git a/examples/apps/slack-echo-command/template.yaml b/examples/apps/slack-echo-command/template.yaml deleted file mode 100644 index 1f413f5f6a..0000000000 --- a/examples/apps/slack-echo-command/template.yaml +++ /dev/null @@ -1,32 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - A function that handles a Slack slash command and echoes the details back to - the user. -Parameters: - KeyIdParameter: - Type: String -Resources: - slackechocommand: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - A function that handles a Slack slash command and echoes the details - back to the user. - MemorySize: 128 - Timeout: 3 - Policies: - - KMSDecryptPolicy: - KeyId: !Ref KeyIdParameter - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY - Environment: - Variables: - kmsEncryptedToken: diff --git a/examples/apps/sns-message-python/lambda_function.py b/examples/apps/sns-message-python/lambda_function.py deleted file mode 100644 index b6f38de0da..0000000000 --- a/examples/apps/sns-message-python/lambda_function.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import print_function - -import json - -print('Loading function') - - -def lambda_handler(event, context): - #print("Received event: " + json.dumps(event, indent=2)) - message = event['Records'][0]['Sns']['Message'] - print("From SNS: " + message) - return message diff --git a/examples/apps/sns-message-python/template.yaml b/examples/apps/sns-message-python/template.yaml deleted file mode 100644 index b1a0daf184..0000000000 --- a/examples/apps/sns-message-python/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon SNS trigger that logs the message pushed to the SNS topic. -Resources: - snsmessagepython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: An Amazon SNS trigger that logs the message pushed to the SNS topic. - MemorySize: 128 - Timeout: 3 - Events: - SNS1: - Type: SNS - Properties: - Topic: - Ref: SNSTopic1 - SNSTopic1: - Type: 'AWS::SNS::Topic' diff --git a/examples/apps/sns-message/index.js b/examples/apps/sns-message/index.js deleted file mode 100644 index c2e7bd3f49..0000000000 --- a/examples/apps/sns-message/index.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -exports.handler = (event, context, callback) => { - //console.log('Received event:', JSON.stringify(event, null, 2)); - const message = event.Records[0].Sns.Message; - console.log('From SNS:', message); - callback(null, message); -}; diff --git a/examples/apps/sns-message/template.yaml b/examples/apps/sns-message/template.yaml deleted file mode 100644 index 140c61f9c2..0000000000 --- a/examples/apps/sns-message/template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: An Amazon SNS trigger that logs the message pushed to the SNS topic. -Resources: - snsmessage: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: An Amazon SNS trigger that logs the message pushed to the SNS topic. - MemorySize: 128 - Timeout: 3 - Events: - SNS1: - Type: SNS - Properties: - Topic: - Ref: SNSTopic1 - SNSTopic1: - Type: 'AWS::SNS::Topic' diff --git a/examples/apps/splunk-cloudwatch-logs-processor/index.js b/examples/apps/splunk-cloudwatch-logs-processor/index.js deleted file mode 100644 index 995e8c633e..0000000000 --- a/examples/apps/splunk-cloudwatch-logs-processor/index.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Stream events from AWS CloudWatch Logs to Splunk - * - * This function streams AWS CloudWatch Logs to Splunk using - * Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to stream logs to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); -const zlib = require('zlib'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - - // CloudWatch Logs data is base64 encoded so decode here - const payload = new Buffer(event.awslogs.data, 'base64'); - // CloudWatch Logs are gzip compressed so expand here - zlib.gunzip(payload, (err, result) => { - if (err) { - callback(err); - } else { - const parsed = JSON.parse(result.toString('ascii')); - console.log('Decoded payload:', JSON.stringify(parsed, null, 2)); - let count = 0; - if (parsed.logEvents) { - parsed.logEvents.forEach((item) => { - /* Log event to Splunk with explicit event timestamp. - - Use optional 'context' argument to send Lambda metadata e.g. awsRequestId, functionName. - - Change "item.timestamp" below if time is specified in another field in the event. - - Change to "logger.log(item.message, context)" if no time field is present in event. */ - logger.logWithTime(item.timestamp, item.message, context); - - /* Alternatively, UNCOMMENT logger call below if you want to override Splunk input settings */ - /* Log event to Splunk with any combination of explicit timestamp, index, source, sourcetype, and host. - - Complete list of input settings available at http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector */ - // logger.logEvent({ - // time: new Date(item.timestamp).getTime() / 1000, - // host: 'serverless', - // source: `lambda:${context.functionName}`, - // sourcetype: 'httpevent', - // index: 'main', - // event: item.message, - // }); - - count += 1; - }); - } - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - console.log(`Successfully processed ${count} log event(s).`); - callback(null, count); // Return number of log events - } - }); - } - }); -}; diff --git a/examples/apps/splunk-cloudwatch-logs-processor/lib/mysplunklogger.js b/examples/apps/splunk-cloudwatch-logs-processor/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/splunk-cloudwatch-logs-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-cloudwatch-logs-processor/template.yaml b/examples/apps/splunk-cloudwatch-logs-processor/template.yaml deleted file mode 100644 index e53e82b9e5..0000000000 --- a/examples/apps/splunk-cloudwatch-logs-processor/template.yaml +++ /dev/null @@ -1,28 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Stream events from AWS CloudWatch Logs to Splunk's HTTP event collector -Parameters: - BucketNameParameter: - Type: String - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunkcloudwatchlogsprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Stream events from AWS CloudWatch Logs to Splunk's HTTP event collector - MemorySize: 512 - Timeout: 10 - Policies: - - S3CrudPolicy: - BucketName: !Ref BucketNameParameter - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter diff --git a/examples/apps/splunk-dynamodb-stream-processor/index.js b/examples/apps/splunk-dynamodb-stream-processor/index.js deleted file mode 100644 index ea31168de7..0000000000 --- a/examples/apps/splunk-dynamodb-stream-processor/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Stream events from AWS DynamoDB Stream to Splunk - * - * This function streams AWS DynamoDB Stream events to Splunk using - * Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to stream events to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - let count = 0; - - event.Records.forEach((record) => { - console.log('DynamoDB Record: %j', record.dynamodb); - - /* Log event to Splunk - - Use optional 'context' argument to send Lambda metadata e.g. awsRequestId, functionName. - - Change to "logger.logWithTime(, item, context)" to explicitly set event timestamp */ - logger.log(record, context); - - /* Alternatively, UNCOMMENT logger call below if you want to override Splunk input settings */ - /* Log event to Splunk with any combination of explicit timestamp, index, source, sourcetype, and host. - - Complete list of input settings available at http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector */ - // logger.logEvent({ - // host: 'serverless', - // source: `lambda:${context.functionName}`, - // sourcetype: 'httpevent', - // index: 'main', - // event: record, - // }); - - count += 1; - }); - - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - console.log(`Successfully processed ${count} record(s).`); - callback(null, count); // Return number of records processed - } - }); -}; diff --git a/examples/apps/splunk-dynamodb-stream-processor/lib/mysplunklogger.js b/examples/apps/splunk-dynamodb-stream-processor/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/splunk-dynamodb-stream-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-dynamodb-stream-processor/template.yaml b/examples/apps/splunk-dynamodb-stream-processor/template.yaml deleted file mode 100644 index a089fd0d40..0000000000 --- a/examples/apps/splunk-dynamodb-stream-processor/template.yaml +++ /dev/null @@ -1,52 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Stream AWS DynamoDB table activity from DynamoDB Stream to Splunk's HTTP event - collector -Parameters: - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunkdynamodbstreamprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: >- - Stream AWS DynamoDB table activity from DynamoDB Stream to Splunk's HTTP - event collector - MemorySize: 512 - Timeout: 10 - Policies: [] - Events: - DynamoDB1: - Type: DynamoDB - Properties: - Stream: - 'Fn::GetAtt': - - Table1 - - StreamArn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter - Table1: - Type: 'AWS::DynamoDB::Table' - Properties: - AttributeDefinitions: - - AttributeName: id - AttributeType: S - KeySchema: - - AttributeName: id - KeyType: HASH - ProvisionedThroughput: - ReadCapacityUnits: 5 - WriteCapacityUnits: 5 - StreamSpecification: - StreamViewType: NEW_IMAGE diff --git a/examples/apps/splunk-elb-application-access-logs-processor/index.js b/examples/apps/splunk-elb-application-access-logs-processor/index.js deleted file mode 100644 index f43c22e16d..0000000000 --- a/examples/apps/splunk-elb-application-access-logs-processor/index.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Forward Application Load Balancer Access Logs from S3 to Splunk via AWS Lambda - * - * This function streams events to Splunk Enterprise using Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to log to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); -const aws = require('aws-sdk'); -const zlib = require('zlib'); - -const logger = new SplunkLogger(loggerConfig); -const s3 = new aws.S3({ apiVersion: '2006-03-01' }); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - - // Get the object from the event and show its content type - const bucket = event.Records[0].s3.bucket.name; - const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); - const params = { - Bucket: bucket, - Key: key, - }; - s3.getObject(params, (err, data) => { - if (err) { - console.log(err); - const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; - console.log(message); - callback(message); - } else { - console.log(`Retrieved access log: LastModified="${data.LastModified}" ContentLength=${data.ContentLength}`); - const payload = data.Body; - - zlib.gunzip(payload, (err, result) => { // eslint-disable-line no-shadow - if (err) { - console.log(err); - callback(err); - } else { - const parsed = result.toString('ascii'); - const logEvents = parsed.split('\n'); - let count = 0; - let time; - - if (logEvents) { - logEvents.forEach((logEntry) => { - if (logEntry) { - // Extract timestamp as 2nd field in log entry - // For more details: http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-log-entry-format - time = logEntry.split(' ')[1]; - // Log event with specific host, source & sourcetype - // Full list of request parameters available on this page - click on [Expand]: - // http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector - logger.logEvent({ - time: new Date(time).getTime() / 1000, - host: 'serverless', - source: `s3://${bucket}/${key}`, - sourcetype: 'aws:elb:accesslogs', - event: logEntry, - }); - count += 1; - } - }); - console.log(`Processed ${count} log entries`); - } - - logger.flushAsync((err, response) => { // eslint-disable-line no-shadow - if (err) { - callback(err); - } else { - console.log(`Response from Splunk:\n${response}`); - callback(null, count); // Echo number of events forwarded - } - }); - } - }); - } - }); -}; diff --git a/examples/apps/splunk-elb-application-access-logs-processor/lib/mysplunklogger.js b/examples/apps/splunk-elb-application-access-logs-processor/lib/mysplunklogger.js deleted file mode 100644 index 2e5467bf75..0000000000 --- a/examples/apps/splunk-elb-application-access-logs-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } else { - console.log('Sent'); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-elb-application-access-logs-processor/template.yaml b/examples/apps/splunk-elb-application-access-logs-processor/template.yaml deleted file mode 100644 index 4cbf9aa661..0000000000 --- a/examples/apps/splunk-elb-application-access-logs-processor/template.yaml +++ /dev/null @@ -1,40 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Stream Application ELB access logs from S3 to Splunk's HTTP event collector -Parameters: - BucketNameParameter: - Type: String - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunkelbapplicationaccesslogsprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: >- - Stream Application ELB access logs from S3 to Splunk's HTTP event - collector - MemorySize: 512 - Timeout: 10 - Policies: - - S3CrudPolicy: - BucketName: !Ref BucketNameParameter - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: - Ref: Bucket1 - Events: - - 's3:ObjectCreated:*' - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter - Bucket1: - Type: 'AWS::S3::Bucket' diff --git a/examples/apps/splunk-elb-classic-access-logs-processor/index.js b/examples/apps/splunk-elb-classic-access-logs-processor/index.js deleted file mode 100644 index 93c81de062..0000000000 --- a/examples/apps/splunk-elb-classic-access-logs-processor/index.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Forward Classic Load Balancer Access Logs from S3 to Splunk via AWS Lambda - * - * This function streams events to Splunk Enterprise using Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to log to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); -const aws = require('aws-sdk'); - -const logger = new SplunkLogger(loggerConfig); -const s3 = new aws.S3({ apiVersion: '2006-03-01' }); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - - // Get the S3 object from the S3 put event - const bucket = event.Records[0].s3.bucket.name; - const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); - const params = { - Bucket: bucket, - Key: key, - }; - s3.getObject(params, (err, data) => { - if (err) { - console.log(err); - const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; - console.log(message); - callback(message); - } else { - console.log(`Retrieved access log: LastModified="${data.LastModified}" ContentLength=${data.ContentLength}`); - const payload = data.Body; - const parsed = payload.toString('ascii'); - const logEntries = parsed.split('\n'); - let count = 0; - let time; - - if (logEntries) { - logEntries.forEach((logEntry) => { - if (logEntry) { - // Extract timestamp as 1st field in log entry - // For more details: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/access-log-collection.html#access-log-entry-format - time = logEntry.split(' ')[0]; - // Log event with specific host, source & sourcetype - // Full list of request parameters available on this page - click on [Expand]: - // http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector - logger.logEvent({ - time: new Date(time).getTime() / 1000, - host: 'serverless', - source: `s3://${bucket}/${key}`, - sourcetype: 'aws:elb:accesslogs', - event: logEntry, - }); - count += 1; - } - }); - console.log(`Processed ${count} log entries`); - } - - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - callback(null, count); // Echo number of events forwarded - } - }); - } - }); -}; diff --git a/examples/apps/splunk-elb-classic-access-logs-processor/lib/mysplunklogger.js b/examples/apps/splunk-elb-classic-access-logs-processor/lib/mysplunklogger.js deleted file mode 100644 index 2e5467bf75..0000000000 --- a/examples/apps/splunk-elb-classic-access-logs-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } else { - console.log('Sent'); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-elb-classic-access-logs-processor/template.yaml b/examples/apps/splunk-elb-classic-access-logs-processor/template.yaml deleted file mode 100644 index 562c13e8c7..0000000000 --- a/examples/apps/splunk-elb-classic-access-logs-processor/template.yaml +++ /dev/null @@ -1,38 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Stream Classic ELB access logs from S3 to Splunk's HTTP event collector -Parameters: - BucketNameParameter: - Type: String - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunkelbclassicaccesslogsprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Stream Classic ELB access logs from S3 to Splunk's HTTP event collector - MemorySize: 512 - Timeout: 10 - Policies: - - S3CrudPolicy: - BucketName: !Ref BucketNameParameter - Events: - BucketEvent1: - Type: S3 - Properties: - Bucket: - Ref: Bucket1 - Events: - - 's3:ObjectCreated:*' - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter - Bucket1: - Type: 'AWS::S3::Bucket' diff --git a/examples/apps/splunk-iot-processor/index.js b/examples/apps/splunk-iot-processor/index.js deleted file mode 100644 index e3b59ffc9e..0000000000 --- a/examples/apps/splunk-iot-processor/index.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Stream events from AWS IoT to Splunk - * - * This function streams AWS IoT events to Splunk using - * Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to stream events to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - * - * Once Lambda function created, add an AWS IoT Rule with Lambda action set to this function name. - * For more details, including adding permissions to AWS IoT to invoke Lambda, refer to AWS Docs: - * http://docs.aws.amazon.com/iot/latest/developerguide/iot-lambda-rule.html#iot-create-lambda-rule - * http://docs.aws.amazon.com/iot/latest/developerguide/lambda-rule.html - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - - /* Send event to Splunk - - Use optional 'context' argument to send Lambda metadata e.g. awsRequestId, functionName. - - Change to "logger.logWithTime(, item, context)" if you want to - explicitly set event timestamp */ - logger.log(event, context); - - /* Alternatively, UNCOMMENT logger call below if you want to override Splunk input settings */ - /* Send event to Splunk with explicit timestamp, index, source, sourcetype, and/or host. - - Complete list of input settings available at http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector */ - // logger.logEvent({ - // time: Date.now(), - // host: 'serverless', - // source: `lambda:${context.functionName}`, - // sourcetype: 'httpevent', - // index: 'main', - // event: event, - // }); - - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - callback(null, event); // Echo back event itself - } - }); -}; diff --git a/examples/apps/splunk-iot-processor/lib/mysplunklogger.js b/examples/apps/splunk-iot-processor/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/splunk-iot-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-iot-processor/template.yaml b/examples/apps/splunk-iot-processor/template.yaml deleted file mode 100644 index 677c545ab0..0000000000 --- a/examples/apps/splunk-iot-processor/template.yaml +++ /dev/null @@ -1,24 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Stream events from AWS IoT to Splunk's HTTP event collector -Parameters: - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunkiotprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Stream events from AWS IoT to Splunk's HTTP event collector - MemorySize: 512 - Timeout: 10 - Policies: [] - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter diff --git a/examples/apps/splunk-kinesis-stream-processor/index.js b/examples/apps/splunk-kinesis-stream-processor/index.js deleted file mode 100644 index 30cadf657a..0000000000 --- a/examples/apps/splunk-kinesis-stream-processor/index.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Stream events from AWS Kinesis to Splunk - * - * This function streams AWS Kinesis events to Splunk using - * Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to stream events to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - let count = 0; - - event.Records.forEach((record) => { - // Kinesis data is base64 encoded so decode here - const data = new Buffer(record.kinesis.data, 'base64').toString('ascii'); - let item = null; - - /* NOTE: if Kinesis stream records originates from CloudWatch Logs, data is - compressed and needs to be expanded here. Refer to 'splunk-cloudwatch-log-processor' - blueprint in AWS Lambda console for sample code using zlib */ - - console.log('Decoded payload:', JSON.stringify(data, null, 2)); - - try { - item = JSON.parse(data); - } catch (exception) { - item = data; - } - - /* Log event to Splunk - - Use optional 'context' argument to send Lambda metadata e.g. awsRequestId, functionName. - - Change to "logger.logWithTime(, item, context)" to explicitly set event timestamp */ - logger.log(item, context); - - /* Alternatively, UNCOMMENT logger call below if you want to override Splunk input settings */ - /* Log event to Splunk with any combination of explicit timestamp, index, source, sourcetype, and host. - - Complete list of input settings available at http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector */ - // logger.logEvent({ - // time: record.kinesis.approximateArrivalTimestamp, - // host: 'serverless', - // source: `lambda:${context.functionName}`, - // sourcetype: 'httpevent', - // index: 'main', - // event: item, - // }); - - count += 1; - }); - - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - console.log(`Successfully processed ${count} record(s).`); - callback(null, count); // Return number of records processed - } - }); -}; diff --git a/examples/apps/splunk-kinesis-stream-processor/lib/mysplunklogger.js b/examples/apps/splunk-kinesis-stream-processor/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/splunk-kinesis-stream-processor/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-kinesis-stream-processor/template.yaml b/examples/apps/splunk-kinesis-stream-processor/template.yaml deleted file mode 100644 index 60ebe7dcb4..0000000000 --- a/examples/apps/splunk-kinesis-stream-processor/template.yaml +++ /dev/null @@ -1,38 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Stream events from AWS Kinesis to Splunk's HTTP event collector -Parameters: - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunkkinesisstreamprocessor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: Stream events from AWS Kinesis to Splunk's HTTP event collector - MemorySize: 512 - Timeout: 10 - Policies: [] - Events: - Kinesis1: - Type: Kinesis - Properties: - Stream: - 'Fn::GetAtt': - - KinesisStream1 - - Arn - StartingPosition: TRIM_HORIZON - BatchSize: 100 - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter - KinesisStream1: - Type: 'AWS::Kinesis::Stream' - Properties: - ShardCount: 1 diff --git a/examples/apps/splunk-logging/index.js b/examples/apps/splunk-logging/index.js deleted file mode 100644 index 1b42ff8340..0000000000 --- a/examples/apps/splunk-logging/index.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Splunk logging for AWS Lambda - * - * This function logs to a Splunk host using Splunk's HTTP event collector API. - * - * Define the following Environment Variables in the console below to configure - * this function to log to your Splunk host: - * - * 1. SPLUNK_HEC_URL: URL address for your Splunk HTTP event collector endpoint. - * Default port for event collector is 8088. Example: https://host.com:8088/services/collector - * - * 2. SPLUNK_HEC_TOKEN: Token for your Splunk HTTP event collector. - * To create a new token for this Lambda function, refer to Splunk Docs: - * http://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector#Create_an_Event_Collector_token - */ - -'use strict'; - -const loggerConfig = { - url: process.env.SPLUNK_HEC_URL, - token: process.env.SPLUNK_HEC_TOKEN, -}; - -const SplunkLogger = require('./lib/mysplunklogger'); - -const logger = new SplunkLogger(loggerConfig); - -exports.handler = (event, context, callback) => { - console.log('Received event:', JSON.stringify(event, null, 2)); - - // Log JSON objects to Splunk - logger.log(event); - - // Log JSON objects with optional 'context' argument (recommended) - // This adds valuable Lambda metadata including functionName as source, awsRequestId as field - logger.log(event, context); - - // Log strings - logger.log(`value1 = ${event.key1}`, context); - - // Log with user-specified timestamp - useful for forwarding events with embedded - // timestamps, such as from AWS IoT, AWS Kinesis, AWS CloudWatch Logs - // Change "Date.now()" below to event timestamp if specified in event payload - logger.logWithTime(Date.now(), event, context); - - // Advanced: - // Log event with user-specified request parameters - useful to set input settings per event vs token-level - // Full list of request parameters available here: - // http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector - logger.logEvent({ - time: Date.now(), - host: 'serverless', - source: `lambda:${context.functionName}`, - sourcetype: 'httpevent', - event: event, - }); - - // Send all the events in a single batch to Splunk - logger.flushAsync((error, response) => { - if (error) { - callback(error); - } else { - console.log(`Response from Splunk:\n${response}`); - callback(null, event.key1); // Echo back the first key value - } - }); -}; diff --git a/examples/apps/splunk-logging/lib/mysplunklogger.js b/examples/apps/splunk-logging/lib/mysplunklogger.js deleted file mode 100644 index 79ef74151d..0000000000 --- a/examples/apps/splunk-logging/lib/mysplunklogger.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict'; - -const url = require('url'); - -const Logger = function Logger(config) { - this.url = config.url; - this.token = config.token; - - this.addMetadata = true; - this.setSource = true; - - this.parsedUrl = url.parse(this.url); - // eslint-disable-next-line import/no-dynamic-require - this.requester = require(this.parsedUrl.protocol.substring(0, this.parsedUrl.protocol.length - 1)); - // Initialize request options which can be overridden & extended by consumer as needed - this.requestOptions = { - hostname: this.parsedUrl.hostname, - path: this.parsedUrl.path, - port: this.parsedUrl.port, - method: 'POST', - headers: { - Authorization: `Splunk ${this.token}`, - }, - rejectUnauthorized: false, - }; - - this.payloads = []; -}; - -// Simple logging API for Lambda functions -Logger.prototype.log = function log(message, context) { - this.logWithTime(Date.now(), message, context); -}; - -Logger.prototype.logWithTime = function logWithTime(time, message, context) { - const payload = {}; - - if (Object.prototype.toString.call(message) === '[object Array]') { - throw new Error('message argument must be a string or a JSON object.'); - } - payload.event = message; - - // Add Lambda metadata - if (typeof context !== 'undefined') { - if (this.addMetadata) { - // Enrich event only if it is an object - if (message === Object(message)) { - payload.event = JSON.parse(JSON.stringify(message)); // deep copy - payload.event.awsRequestId = context.awsRequestId; - } - } - if (this.setSource) { - payload.source = `lambda:${context.functionName}`; - } - } - - payload.time = new Date(time).getTime() / 1000; - - this.logEvent(payload); -}; - -Logger.prototype.logEvent = function logEvent(payload) { - this.payloads.push(JSON.stringify(payload)); -}; - -Logger.prototype.flushAsync = function flushAsync(callback) { - callback = callback || (() => {}); // eslint-disable-line no-param-reassign - - console.log('Sending event(s)'); - const req = this.requester.request(this.requestOptions, (res) => { - res.setEncoding('utf8'); - - console.log('Response received'); - res.on('data', (data) => { - let error = null; - if (res.statusCode !== 200) { - error = new Error(`error: statusCode=${res.statusCode}\n\n${data}`); - console.error(error); - } - this.payloads.length = 0; - callback(error, data); - }); - }); - - req.on('error', (error) => { - callback(error); - }); - - req.end(this.payloads.join(''), 'utf8'); -}; - -module.exports = Logger; diff --git a/examples/apps/splunk-logging/template.yaml b/examples/apps/splunk-logging/template.yaml deleted file mode 100644 index c6b218c19b..0000000000 --- a/examples/apps/splunk-logging/template.yaml +++ /dev/null @@ -1,30 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Demonstrates logging from AWS Lambda code to Splunk's HTTP event collector -Parameters: - BucketNameParameter: - Type: String - SplunkHecUrlParameter: - Type: String - AllowedPattern: '^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$' - SplunkHecTokenParameter: - Type: String -Resources: - splunklogging: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: >- - Demonstrates logging from AWS Lambda code to Splunk's HTTP event - collector - MemorySize: 512 - Timeout: 10 - Policies: - - S3CrudPolicy: - BucketName: !Ref BucketNameParameter - Environment: - Variables: - SPLUNK_HEC_URL: !Ref SplunkHecUrlParameter - SPLUNK_HEC_TOKEN: !Ref SplunkHecTokenParameter diff --git a/examples/apps/sqs-poller/index.js b/examples/apps/sqs-poller/index.js deleted file mode 100644 index a6142f2073..0000000000 --- a/examples/apps/sqs-poller/index.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; - -const AWS = require('aws-sdk'); - -const SQS = new AWS.SQS({ apiVersion: '2012-11-05' }); -const Lambda = new AWS.Lambda({ apiVersion: '2015-03-31' }); - - -// Your queue URL stored in the queueUrl environment variable -const QUEUE_URL = process.env.queueUrl; -const PROCESS_MESSAGE = 'process-message'; - - -function invokePoller(functionName, message) { - const payload = { - operation: PROCESS_MESSAGE, - message, - }; - const params = { - FunctionName: functionName, - InvocationType: 'Event', - Payload: new Buffer(JSON.stringify(payload)), - }; - return new Promise((resolve, reject) => { - Lambda.invoke(params, (err) => (err ? reject(err) : resolve())); - }); -} - - -function processMessage(message, callback) { - console.log(message); - - // TODO process message - - // delete message - const params = { - QueueUrl: QUEUE_URL, - ReceiptHandle: message.ReceiptHandle, - }; - SQS.deleteMessage(params, (err) => callback(err, message)); -} - -function poll(functionName, callback) { - const params = { - QueueUrl: QUEUE_URL, - MaxNumberOfMessages: 10, - VisibilityTimeout: 10, - }; - // batch request messages - SQS.receiveMessage(params, (err, data) => { - if (err) { - return callback(err); - } - // for each message, reinvoke the function - const promises = data.Messages.map((message) => invokePoller(functionName, message)); - // complete when all invocations have been made - Promise.all(promises).then(() => { - const result = `Messages received: ${data.Messages.length}`; - console.log(result); - callback(null, result); - }); - }); -} - -exports.handler = (event, context, callback) => { - try { - if (event.operation === PROCESS_MESSAGE) { - // invoked by poller - processMessage(event.message, callback); - } else { - // invoked by schedule - poll(context.functionName, callback); - } - } catch (err) { - callback(err); - } -}; diff --git a/examples/apps/sqs-poller/template.yaml b/examples/apps/sqs-poller/template.yaml deleted file mode 100644 index eeed0c18e0..0000000000 --- a/examples/apps/sqs-poller/template.yaml +++ /dev/null @@ -1,27 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Periodically polls an SQS queue and asynchronously consumes each message. -Parameters: - QueueNameParameter: - Type: String - Description: - QueueUrlParameter: - Type: String - AllowedPattern: '^https:\/\/sqs\.[a-z\-0-9]+\.amazonaws\.com(?:.cn)?\/[0-9]{12}\/.{1,80}$' -Resources: - sqspoller: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Periodically polls an SQS queue and asynchronously consumes each message. - MemorySize: 128 - Timeout: 10 - Policies: - - SQSPollerPolicy: - QueueName: !Ref QueueNameParameter - Environment: - Variables: - queueUrl: !Ref QueueUrlParameter diff --git a/examples/apps/step-functions-error-python/lambda_function.py b/examples/apps/step-functions-error-python/lambda_function.py deleted file mode 100644 index d92f36b321..0000000000 --- a/examples/apps/step-functions-error-python/lambda_function.py +++ /dev/null @@ -1,5 +0,0 @@ -def lambda_handler(event, context): - class CustomException(Exception): - pass - - raise CustomException('This is a custom error!') diff --git a/examples/apps/step-functions-error-python/template.yaml b/examples/apps/step-functions-error-python/template.yaml deleted file mode 100644 index cdd996d601..0000000000 --- a/examples/apps/step-functions-error-python/template.yaml +++ /dev/null @@ -1,18 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An AWS Lambda function that throws an error. AWS Step Functions state machines can be configured to handle (catch or retry) this error. -Resources: - stepfunctionserrorpython: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: >- - An AWS Lambda function that throws an error. AWS Step Functions state machines can be configured to handle (catch or retry) this error. - MemorySize: 128 - Timeout: 3 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} \ No newline at end of file diff --git a/examples/apps/step-functions-error/index.js b/examples/apps/step-functions-error/index.js deleted file mode 100644 index 3a7aef3b48..0000000000 --- a/examples/apps/step-functions-error/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -exports.handler = (event, context, callback) => { - function CustomError(message) { - this.name = 'CustomError'; - this.message = message; - } - CustomError.prototype = new Error(); - - const error = new CustomError('This is a custom error!'); - callback(error); -}; diff --git a/examples/apps/step-functions-error/template.yaml b/examples/apps/step-functions-error/template.yaml deleted file mode 100644 index 847cce444d..0000000000 --- a/examples/apps/step-functions-error/template.yaml +++ /dev/null @@ -1,18 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - An AWS Lambda function that throws an error. AWS Step Functions state machines can be configured to handle (catch or retry) this error. -Resources: - stepfunctionserror: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs6.10 - CodeUri: . - Description: >- - An AWS Lambda function that throws an error. AWS Step Functions state machines can be configured to handle (catch or retry) this error. - MemorySize: 128 - Timeout: 3 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} diff --git a/examples/apps/step-functions-send-to-sns/lambda_function.py b/examples/apps/step-functions-send-to-sns/lambda_function.py deleted file mode 100644 index 4028296534..0000000000 --- a/examples/apps/step-functions-send-to-sns/lambda_function.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import print_function - -import json -import urllib -import boto3 - -print('Loading message function...') - - -def send_to_sns(message, context): - - # This function receives JSON input with three fields: the ARN of an SNS topic, - # a string with the subject of the message, and a string with the body of the message. - # The message is then sent to the SNS topic. - # - # Example: - # { - # "topic": "arn:aws:sns:REGION:123456789012:MySNSTopic", - # "subject": "This is the subject of the message.", - # "message": "This is the body of the message." - # } - - sns = boto3.client('sns') - sns.publish( - TopicArn=message['topic'], - Subject=message['subject'], - Message=message['body'] - ) - - return ('Sent a message to an Amazon SNS topic.') diff --git a/examples/apps/step-functions-send-to-sns/template.yaml b/examples/apps/step-functions-send-to-sns/template.yaml deleted file mode 100644 index 2840cc3d8a..0000000000 --- a/examples/apps/step-functions-send-to-sns/template.yaml +++ /dev/null @@ -1,19 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Sends an SNS message from input JSON -Parameters: - TopicNameParameter: - Type: String -Resources: - stepfunctionssendtosns: - Type: 'AWS::Serverless::Function' - Properties: - Handler: lambda_function.send_to_sns - Runtime: python2.7 - CodeUri: . - Description: Sends an SNS message from input JSON - MemorySize: 128 - Timeout: 3 - Policies: - - SNSPublishMessagePolicy: - TopicName: !Ref TopicNameParameter \ No newline at end of file diff --git a/examples/apps/sumologic-process-logs/index.js b/examples/apps/sumologic-process-logs/index.js deleted file mode 100644 index 108a6a052e..0000000000 --- a/examples/apps/sumologic-process-logs/index.js +++ /dev/null @@ -1,215 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////// -// CloudWatch Logs to SumoLogic // -// https://github.com/SumoLogic/sumologic-aws-lambda/tree/master/cloudwatchlogs // -////////////////////////////////////////////////////////////////////////////////// - -// SumoLogic Endpoint to post logs -/* eslint-disable */ -var SumoURL = process.env.SUMO_ENDPOINT; - -// The following parameters override the sourceCategoryOverride, sourceHostOverride and sourceNameOverride metadata fields within SumoLogic. -// Not these can also be overridden via json within the message payload. See the README for more information. -var sourceCategoryOverride = process.env.SOURCE_CATEGORY_OVERRIDE || 'none'; // If none sourceCategoryOverride will not be overridden -var sourceHostOverride = process.env.SOURCE_HOST_OVERRIDE || 'none'; // If none sourceHostOverride will not be set to the name of the logGroup -var sourceNameOverride = process.env.SOURCE_NAME_OVERRIDE || 'none'; // If none sourceNameOverride will not be set to the name of the logStream - -// CloudWatch logs encoding -var encoding = process.env.ENCODING || 'utf-8'; // default is utf-8 - -// Include logStream and logGroup as json fields within the message. Required for SumoLogic AWS Lambda App -var includeLogInfo = true; // default is true - -// Regex used to detect logs coming from lambda functions. -// The regex will parse out the requestID and strip the timestamp -// Example: 2016-11-10T23:11:54.523Z 108af3bb-a79b-11e6-8bd7-91c363cc05d9 some message -var consoleFormatRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z\t(\w+?-\w+?-\w+?-\w+?-\w+)\t/; - -// Used to extract RequestID -var requestIdRegex = /(?:RequestId:|Z)\s+([\w\d\-]+)/; - -var https = require('https'); -var zlib = require('zlib'); -var url = require('url'); - -function sumoMetaKey(awslogsData, message) { - var sourceCategory = ''; - var sourceName = ''; - var sourceHost = ''; - - if (sourceCategoryOverride !== null && sourceCategoryOverride !== '' && sourceCategoryOverride != 'none') { - sourceCategory = sourceCategoryOverride; - } - - if (sourceHostOverride !== null && sourceHostOverride !== '' && sourceHostOverride != 'none') { - sourceHost = sourceHostOverride; - } else { - sourceHost = awslogsData.logGroup; - } - - if (sourceNameOverride !== null && sourceNameOverride !== '' && sourceNameOverride != 'none') { - sourceName = sourceNameOverride; - } else { - sourceName = awslogsData.logStream; - } - - // Ability to override metadata within the message - // Useful within Lambda function console.log to dynamically set metadata fields within SumoLogic. - if (message.hasOwnProperty('_sumo_metadata')) { - var metadataOverride = message._sumo_metadata; - if (metadataOverride.category) { - sourceCategory = metadataOverride.category; - } - if (metadataOverride.host) { - sourceHost = metadataOverride.host; - } - if (metadataOverride.source) { - sourceName = metadataOverride.source; - } - delete message._sumo_metadata; - } - return sourceName + ':' + sourceCategory + ':' + sourceHost; - -} - -function postToSumo(context, messages) { - var messagesTotal = Object.keys(messages).length; - var messagesSent = 0; - var messageErrors = []; - - var urlObject = url.parse(SumoURL); - var options = { - 'hostname': urlObject.hostname, - 'path': urlObject.pathname, - 'method': 'POST' - }; - - var finalizeContext = function () { - var total = messagesSent + messageErrors.length; - if (total == messagesTotal) { - console.log('messagesSent: ' + messagesSent + ' messagesErrors: ' + messageErrors.length); - if (messageErrors.length > 0) { - context.fail('errors: ' + messageErrors); - } else { - context.succeed(); - } - } - }; - - - Object.keys(messages).forEach(function (key, index) { - var headerArray = key.split(':'); - - options.headers = { - 'X-Sumo-Name': headerArray[0], - 'X-Sumo-Category': headerArray[1], - 'X-Sumo-Host': headerArray[2] - }; - - var req = https.request(options, function (res) { - res.setEncoding('utf8'); - res.on('data', function (chunk) {}); - res.on('end', function () { - if (res.statusCode == 200) { - messagesSent++; - } else { - messageErrors.push('HTTP Return code ' + res.statusCode); - } - finalizeContext(); - }); - }); - - req.on('error', function (e) { - messageErrors.push(e.message); - finalizeContext(); - }); - - for (var i = 0; i < messages[key].length; i++) { - req.write(JSON.stringify(messages[key][i]) + '\n'); - } - req.end(); - }); -} - - -exports.handler = function (event, context) { - - // Used to hold chunks of messages to post to SumoLogic - var messageList = {}; - - // Validate URL has been set - var urlObject = url.parse(SumoURL); - if (urlObject.protocol != 'https:' || urlObject.host === null || urlObject.path === null) { - context.fail('Invalid SUMO_ENDPOINT environment variable: ' + SumoURL); - } - - var zippedInput = new Buffer(event.awslogs.data, 'base64'); - - zlib.gunzip(zippedInput, function (e, buffer) { - if (e) { - context.fail(e); - } - - var awslogsData = JSON.parse(buffer.toString(encoding)); - - if (awslogsData.messageType === 'CONTROL_MESSAGE') { - console.log('Control message'); - context.succeed('Success'); - } - - var lastRequestID = null; - - console.log('Log events: ' + awslogsData.logEvents.length); - - // Chunk log events before posting to SumoLogic - awslogsData.logEvents.forEach(function (log, idx, arr) { - - // Remove any trailing \n - log.message = log.message.replace(/\n$/, ''); - - // Try extract requestID - var requestId = requestIdRegex.exec(log.message); - if (requestId !== null) { - lastRequestID = requestId[1]; - } - - // Attempt to detect console log and auto extract requestID and message - var consoleLog = consoleFormatRegex.exec(log.message); - if (consoleLog !== null) { - lastRequestID = consoleLog[1]; - log.message = log.message.substring(consoleLog[0].length); - } - - // Auto detect if message is json - try { - log.message = JSON.parse(log.message); - } catch (err) { - // Do nothing, leave as text - log.message.trim(); - } - - // delete id as it's not very useful - delete log.id; - - if (includeLogInfo) { - log.logStream = awslogsData.logStream; - log.logGroup = awslogsData.logGroup; - } - - if (lastRequestID) { - log.requestID = lastRequestID; - } - - var metadataKey = sumoMetaKey(awslogsData, log.message); - - if (metadataKey in messageList) { - messageList[metadataKey].push(log); - } else { - messageList[metadataKey] = [log]; - } - }); - - // Push messages to Sumo - postToSumo(context, messageList); - - }); -}; diff --git a/examples/apps/sumologic-process-logs/template.yaml b/examples/apps/sumologic-process-logs/template.yaml deleted file mode 100644 index 6e1e6b847b..0000000000 --- a/examples/apps/sumologic-process-logs/template.yaml +++ /dev/null @@ -1,16 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Pushes CWL logs to SumoLogic. -Resources: - sumologicprocesslogs: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Pushes CWL logs to SumoLogic. - MemorySize: 128 - Timeout: 10 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} \ No newline at end of file diff --git a/examples/apps/twilio-conference/index.js b/examples/apps/twilio-conference/index.js deleted file mode 100644 index 515e254c00..0000000000 --- a/examples/apps/twilio-conference/index.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -const crypto = require('crypto'); - - -const respond = (callback, contents) => callback(null, { - statusCode: '200', - body: `${contents}`, - headers: { - 'Content-Type': 'application/xml', - }, -}); - - -/** - * Conference allows multiple people to chat together in a conference room. - * - * Example request: /?Name=My+Conference&Password=123&Message=Hello - */ -exports.handler = (event, context, callback) => { - const query = event.queryStringParameters || {}; - - if (query.Password && query.Digits !== query.Password) { - // Password is set, so ask for it (minimum of 3 digits for security) - return respond(callback, ` - - Please enter your conference pass code - - -`); - } - - const response = []; - - if (query.Message && query.Message.trim().substring(0, 4).toLowerCase() === 'http') { - // Play the given message from an HTTP URL - response.push(`${query.Message}`); - } else if (query.Message) { - // Read back the message given - response.push(`${query.Message}`); - } else { - // Default message - response.push('You are now entering the conference line.'); - } - - // Get the conference name or generate a unique hash if none is provided - const name = query.Name || crypto.createHash('md5').update(JSON.stringify(query)).digest('hex'); - - response.push(`${name}`); - - // Flush out response - respond(callback, response.join('')); -}; diff --git a/examples/apps/twilio-conference/template.yaml b/examples/apps/twilio-conference/template.yaml deleted file mode 100644 index 51f9faece6..0000000000 --- a/examples/apps/twilio-conference/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Allows multiple people to chat together in a conference room. -Resources: - twilioconference: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Allows multiple people to chat together in a conference room. - MemorySize: 128 - Timeout: 15 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY diff --git a/examples/apps/twilio-forward/index.js b/examples/apps/twilio-forward/index.js deleted file mode 100644 index 51c3baafa2..0000000000 --- a/examples/apps/twilio-forward/index.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -const respond = (callback, contents) => callback(null, { - statusCode: '200', - body: `${contents}`, - headers: { - 'Content-Type': 'application/xml', - }, -}); - -// e.g. 415-555-1212 --> +14155551212 -const normalizeNumber = (number) => `+1${number.replace(/[^0-9]/g, '')}`; - - -/** - * Forward will forward a call to another phone number. If the call isn't answered - * or the line is busy, the call is optionally forwarded to a new URL. - * - * Example request: /?PhoneNumber=415-555-1212 - */ -exports.handler = (event, context, callback) => { - const query = event.queryStringParameters || {}; - - if (query.DialCallStatus) { - // We're returning from an attempted Dial - const status = query.DialCallStatus; - if (status === 'completed' || status === 'answered' || !query.FailUrl) { - // Answered, or no failure URL given, so just hang up - return respond(callback, ''); - } - // DialStatus was not answered, so redirect to FailUrl - return respond(callback, `${query.FailUrl}`); - } - - // We made it to here, so just dial the number with the optional Timeout given - const failUrl = query.FailUrl ? `?FailUrl=${encodeURIComponent(query.FailUrl)}` : ''; - const action = `${event.path}${failUrl}`; - respond(callback, `${normalizeNumber(query.PhoneNumber)}`); -}; diff --git a/examples/apps/twilio-forward/template.yaml b/examples/apps/twilio-forward/template.yaml deleted file mode 100644 index 7d8bf4b8ca..0000000000 --- a/examples/apps/twilio-forward/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Forward a call to another phone number. -Resources: - twilioforward: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: Forward a call to another phone number. - MemorySize: 128 - Timeout: 15 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY diff --git a/examples/apps/twilio-menu/index.js b/examples/apps/twilio-menu/index.js deleted file mode 100644 index 82279e396e..0000000000 --- a/examples/apps/twilio-menu/index.js +++ /dev/null @@ -1,59 +0,0 @@ -'use strict'; - -const respond = (callback, contents) => callback(null, { - statusCode: '200', - body: `${contents}`, - headers: { - 'Content-Type': 'application/xml', - }, -}); - -const getOptions = (query) => Object.keys(query) - .map((k) => /^Options\[(.*?)\]$/.exec(k)) - .filter((m) => !!m) - .reduce((o, m) => { - const obj = o; - obj[m[1]] = query[m[0]]; - return obj; - }, {}); - - -/** - * Simple Menu will just play a greeting, and wait for the caller to press one - * or more digits on their keypad. Based on what was pressed, call flow is - * directed to a new URL. - * - * Menu options should be encoded as query string parameters of the following - * form: `Options[]=`. - * - * Example request: /?Message=Hi+There&Options[101]=http://bob.com&Options[102]=http://ann.com&Options[0]=http://operator.com - */ -exports.handler = (event, context, callback) => { - const query = event.queryStringParameters || {}; - const options = getOptions(query); - - if (query.Digits) { - // We got here after a Dial attempt - const location = options[query.Digits]; - if (location) { - // Valid option given, redirect - return respond(callback, `${location}`); - } - return respond(callback, "I'm sorry, that wasn't a valid option."); - } - - // Calculate the max number of digits we need to wait for - const maxDigits = Object.keys(options).reduce((a, b) => Math.max(a.length, b.length)); - // Determine the gather action - let action = ''; - if (query.Message && query.Message.trim().substring(0, 4).toLowerCase() === 'http') { - // Play the greeting while accepting digits - action = `${query.Message}`; - } else if (query.Message) { - // Read back the message given - action = `${query.Message}`; - } - - // Add a redirect if nothing was pressed - respond(callback, `${action}`); -}; diff --git a/examples/apps/twilio-menu/template.yaml b/examples/apps/twilio-menu/template.yaml deleted file mode 100644 index 33e39100d4..0000000000 --- a/examples/apps/twilio-menu/template.yaml +++ /dev/null @@ -1,24 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: >- - Play a greeting, and wait for the caller to press one or more digits on their keypad. -Resources: - twiliomenu: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: >- - Play a greeting, and wait for the caller to press one or more digits on their keypad. - MemorySize: 128 - Timeout: 15 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY diff --git a/examples/apps/twilio-simple-blueprint/index.js b/examples/apps/twilio-simple-blueprint/index.js deleted file mode 100644 index 3981738e7f..0000000000 --- a/examples/apps/twilio-simple-blueprint/index.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -console.log('Loading function'); - -const output = ` - - - - Hello Amazon, this is Twilio powered by Lambda - -`; - -exports.handler = (event, context, callback) => callback(null, { - statusCode: '200', - body: output.trim(), - headers: { - 'Content-Type': 'application/xml', - }, -}); diff --git a/examples/apps/twilio-simple-blueprint/template.yaml b/examples/apps/twilio-simple-blueprint/template.yaml deleted file mode 100644 index c83ae347fb..0000000000 --- a/examples/apps/twilio-simple-blueprint/template.yaml +++ /dev/null @@ -1,22 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: A simple backend for handling events sent from Twilio. -Resources: - twiliosimpleblueprint: - Type: 'AWS::Serverless::Function' - Properties: - Handler: index.handler - Runtime: nodejs8.10 - CodeUri: . - Description: A simple backend for handling events sent from Twilio. - MemorySize: 128 - Timeout: 15 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} - Events: - Api1: - Type: Api - Properties: - Path: /MyResource - Method: ANY diff --git a/examples/apps/vpn-conn-monitor/monitor_vpn_lambda.py b/examples/apps/vpn-conn-monitor/monitor_vpn_lambda.py deleted file mode 100644 index 3ff1a6a55a..0000000000 --- a/examples/apps/vpn-conn-monitor/monitor_vpn_lambda.py +++ /dev/null @@ -1,78 +0,0 @@ -''' -To use this blueprint, your function's role must have permissions -to call ec2:DescribeRegions and ec2:DescribeVpnConnections. -For these permissions, you must specify "Resource": "*". - -Example: -{ - "Version": "2012-10-17", - "Statement": [{ - "Sid": "Stmt1443036478000", - "Effect": "Allow", - "Action": [ - "ec2:DescribeRegions", - "ec2:DescribeVpnConnections" - ], - "Resource": "*" - }] -} -''' - -from __future__ import print_function - -import boto3 - -print('Loading function') -cw = boto3.client('cloudwatch') - - -def put_cloudwatch_metric(metric_name, value, vgw, cgw, region): - cw.put_metric_data( - Namespace='VPNStatus', - MetricData=[{ - 'MetricName': metric_name, - 'Value': value, - 'Unit': 'Count', - 'Dimensions': [ - { - 'Name': 'VGW', - 'Value': vgw - }, - { - 'Name': 'CGW', - 'Value': cgw - }, - { - 'Name': 'Region', - 'Value': region - } - ] - }] - ) - - -def lambda_handler(event, context): - ec2 = boto3.client('ec2') - aws_regions = ec2.describe_regions()['Regions'] - num_connections = 0 - for region in aws_regions: - try: - ec2 = boto3.client('ec2', region_name=region['RegionName']) - vpns = ec2.describe_vpn_connections()['VpnConnections'] - for vpn in vpns: - if vpn['State'] == 'available': - num_connections += 1 - active_tunnels = 0 - if vpn['VgwTelemetry'][0]['Status'] == 'UP': - active_tunnels += 1 - if vpn['VgwTelemetry'][1]['Status'] == 'UP': - active_tunnels += 1 - put_cloudwatch_metric(vpn['VpnConnectionId'], - active_tunnels, - vpn['VpnGatewayId'], - vpn['CustomerGatewayId'], - region['RegionName']) - except Exception as e: - print("Exception: " + str(e)) - continue - return num_connections diff --git a/examples/apps/vpn-conn-monitor/template.yaml b/examples/apps/vpn-conn-monitor/template.yaml deleted file mode 100644 index e93d86c25d..0000000000 --- a/examples/apps/vpn-conn-monitor/template.yaml +++ /dev/null @@ -1,16 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' -Description: Monitors VPN connection status of an account in all regions. -Resources: - vpnconnmonitor: - Type: 'AWS::Serverless::Function' - Properties: - Handler: monitor_vpn_lambda.lambda_handler - Runtime: python2.7 - CodeUri: . - Description: Monitors VPN connection status of an account in all regions. - MemorySize: 128 - Timeout: 120 - Policies: - - CloudWatchPutMetricPolicy: {} - - EC2VPNDescribePolicy: {} \ No newline at end of file