├── .editorconfig ├── .firebaserc ├── .gitignore ├── .surgeignore ├── CNAME ├── README.md ├── app ├── app.ts ├── components │ ├── angie │ │ ├── angie.html │ │ └── angie.ts │ └── camera │ │ └── camera.ts ├── pages │ └── home │ │ ├── home.html │ │ ├── home.scss │ │ └── home.ts ├── services │ ├── colors-dictionary.ts │ ├── phrase.ts │ ├── speech.ts │ ├── vision.ts │ └── voice.ts └── theme │ ├── app.core.scss │ ├── app.ios.scss │ ├── app.md.scss │ ├── app.variables.scss │ └── app.wp.scss ├── circle.yml ├── config.xml ├── firebase.json ├── gulpfile.js ├── hooks ├── README.md └── after_prepare │ └── 010_add_platform_class.js ├── ionic.config.json ├── package.json ├── resources ├── android │ ├── icon │ │ ├── drawable-hdpi-icon.png │ │ ├── drawable-ldpi-icon.png │ │ ├── drawable-mdpi-icon.png │ │ ├── drawable-xhdpi-icon.png │ │ ├── drawable-xxhdpi-icon.png │ │ └── drawable-xxxhdpi-icon.png │ └── splash │ │ ├── drawable-land-hdpi-screen.png │ │ ├── drawable-land-ldpi-screen.png │ │ ├── drawable-land-mdpi-screen.png │ │ ├── drawable-land-xhdpi-screen.png │ │ ├── drawable-land-xxhdpi-screen.png │ │ ├── drawable-land-xxxhdpi-screen.png │ │ ├── drawable-port-hdpi-screen.png │ │ ├── drawable-port-ldpi-screen.png │ │ ├── drawable-port-mdpi-screen.png │ │ ├── drawable-port-xhdpi-screen.png │ │ ├── drawable-port-xxhdpi-screen.png │ │ └── drawable-port-xxxhdpi-screen.png ├── icon.png ├── ios │ ├── icon │ │ ├── icon-40.png │ │ ├── icon-40@2x.png │ │ ├── icon-50.png │ │ ├── icon-50@2x.png │ │ ├── icon-60.png │ │ ├── icon-60@2x.png │ │ ├── icon-60@3x.png │ │ ├── icon-72.png │ │ ├── icon-72@2x.png │ │ ├── icon-76.png │ │ ├── icon-76@2x.png │ │ ├── icon-small.png │ │ ├── icon-small@2x.png │ │ ├── icon-small@3x.png │ │ ├── icon.png │ │ └── icon@2x.png │ └── splash │ │ ├── Default-568h@2x~iphone.png │ │ ├── Default-667h.png │ │ ├── Default-736h.png │ │ ├── Default-Landscape-736h.png │ │ ├── Default-Landscape@2x~ipad.png │ │ ├── Default-Landscape~ipad.png │ │ ├── Default-Portrait@2x~ipad.png │ │ ├── Default-Portrait~ipad.png │ │ ├── Default@2x~iphone.png │ │ └── Default~iphone.png └── splash.png ├── sw-precache-config.json ├── tsconfig.json ├── tslint.json ├── typings.json ├── typings ├── browser.d.ts ├── browser │ ├── ambient │ │ ├── es6-shim │ │ │ └── index.d.ts │ │ └── webrtc │ │ │ └── mediastream │ │ │ └── index.d.ts │ └── definitions │ │ └── annyang │ │ └── index.d.ts ├── globals │ ├── es6-shim │ │ ├── index.d.ts │ │ └── typings.json │ └── webrtc │ │ └── mediastream │ │ ├── index.d.ts │ │ └── typings.json ├── index.d.ts ├── main.d.ts ├── main │ ├── ambient │ │ ├── es6-shim │ │ │ └── index.d.ts │ │ └── webrtc │ │ │ └── mediastream │ │ │ └── index.d.ts │ └── definitions │ │ └── annyang │ │ └── index.d.ts └── modules │ └── annyang │ ├── index.d.ts │ └── typings.json └── www ├── 404.html ├── CNAME ├── cordova.js ├── favicon.png ├── images ├── attila.png ├── icon.png ├── letmesee.png ├── logo.png ├── ng-show.mp3 ├── pwa │ ├── android-chrome-36x36.png │ ├── android-chrome-48x48.png │ ├── android-chrome-72x72.png │ ├── android-chrome-96x96.png │ ├── apple-touch-icon-114x114.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-57x57.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-72x72.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── icon.png │ ├── manifest.json │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-70x70.png │ └── safari-pinned-tab.svg ├── urish.png └── wassim.png ├── index.html ├── manifest.json ├── responsivevoice.js └── sw.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false 16 | 17 | [*.json] 18 | insert_final_newline = false 19 | -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "firebase-letmesee" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | www/build/ 3 | platforms/ 4 | plugins/ 5 | .DS_Store 6 | npm-debug.log 7 | *.swp 8 | -------------------------------------------------------------------------------- /.surgeignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/.surgeignore -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | https://angularlabs.2016.angularattack.io 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CircleCI](https://circleci.com/gh/manekinekko/angularattack2016/tree/master.svg?style=svg)](https://circleci.com/gh/manekinekko/angularattack2016/tree/master) 2 | 3 | ## LetMeSee: The assistant app of people with sight loss 4 | 5 |

6 | 7 | # README FIRST 8 | 9 | ## How to use the app 10 | 11 | Go the [https://letmesee.firebaseapp.com](https://letmesee.firebaseapp.com) on your phone or computer. You can ask Angie ([NG](https://youtu.be/aSFfLVxT5vA?t=47s)) the following questions: 12 | 13 | - `my name is [name], i am [name]`: Angie will remember your name. 14 | - `who are you`: Angie will introduce herself. 15 | - `help`, `what should I say`: Angie will help you use the app. 16 | - `let me see`, `show me`, `(describe) what do you see`: Angie will tell you what you can see. 17 | - `how do I look`: Angie will try to guess what is your face expression. 18 | - `what color is this`,`tell me colors`: Angie will try to guess the most dominant color. 19 | - `(can you) read this (for me)`: Angie will read a text for you. 20 | - `and this`, `and now`: Angie will replay your last query. 21 | 22 | 23 | ## local devs 24 | 25 | ```bash 26 | $ # 1) use this command to serve your local dev in your browser (with livereload support) 27 | $ 28 | $ npm run serve 29 | $ 30 | $ # 1.1) push your updates to git (as usual, with your favorit tool) 31 | $ 32 | $ # 2) when ready, build the browser version of the app 33 | $ 34 | $ npm run build 35 | $ 36 | $ # 3) commit all updates to git (with your favorit tool) 37 | $ # MAKE SURE YOU COMMIT sw.js TO GITHUB!! 38 | $ 39 | $ # 4) deploy to surge 40 | $ 41 | $ npm run deploy 42 | $ 43 | $ # 5) push the created tag to git 44 | $ 45 | ``` 46 | 47 | ## Deploy to surge 48 | 49 | ``` 50 | $ npm run deploy 51 | ``` 52 | 53 | ## Access the `https` deployed app (not http) 54 | 55 | ``` 56 | https://letmesee.firebaseapp.com 57 | ``` 58 | ## The team 59 | 60 | *from left to right* 61 | 62 | - Wassim Chegham ([manekinekko](https://github.com/manekinekko)) 63 | - Attila Csanyi ([attilacsanyi](https://github.com/attilacsanyi)) 64 | - Uri Shaked ([urish](https://github.com/urish)) 65 | 66 | Wassim Chegham 67 | Attila Csanyi 68 | Uri Shaked 69 | -------------------------------------------------------------------------------- /app/app.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Component } from '@angular/core'; 3 | import { Vibration } from 'ionic-native'; 4 | import { 5 | Platform, 6 | ionicBootstrap 7 | } from 'ionic-angular'; 8 | 9 | import { HomePage } from './pages/home/home'; 10 | import { Voice } from './services/voice'; 11 | import { Speech } from './services/speech'; 12 | import { Vision } from './services/vision'; 13 | import { Phrase } from './services/phrase'; 14 | 15 | @Component({ 16 | template: '', 17 | providers: [Vision, Speech, Voice, Phrase] 18 | }) 19 | export class MyApp { 20 | 21 | public rootPage: any; 22 | 23 | constructor(platform: Platform, private voice: Voice) { 24 | this.rootPage = HomePage; 25 | 26 | platform.ready().then(() => { 27 | this.voice.start(); 28 | Vibration.vibrate(500); 29 | }); 30 | 31 | } 32 | } 33 | 34 | ionicBootstrap(MyApp); 35 | -------------------------------------------------------------------------------- /app/components/angie/angie.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, OnChanges, HostListener, EventEmitter} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'letmesee-angie', 5 | templateUrl: 'build/components/angie/angie.html' 6 | }) 7 | export class AngieComponent implements OnChanges { 8 | 9 | @Input() speaking: boolean; 10 | @Output('onTap') tap$: EventEmitter; 11 | 12 | public eyebrowsRightUp: boolean = false; 13 | public eyebrowsLeftUp: boolean = false; 14 | private mouthOpen: boolean = false; 15 | private speakTimer: number; 16 | 17 | constructor() { 18 | this.tap$ = new EventEmitter(); 19 | } 20 | 21 | @HostListener('click', ['$event']) 22 | onClick(e) { 23 | this.tap$.emit(true); 24 | } 25 | 26 | ngOnChanges() { 27 | if (this.speakTimer) { 28 | clearInterval(this.speakTimer); 29 | this.mouthOpen = false; 30 | } 31 | if (this.speaking) { 32 | this.speak(); 33 | } 34 | } 35 | 36 | speak() { 37 | this.speakTimer = setInterval(() => { 38 | this.mouthOpen = this.randomBool(); 39 | this.eyebrowsLeftUp = this.randomBool(); 40 | this.eyebrowsRightUp = this.randomBool(); 41 | }, 200); 42 | } 43 | 44 | private randomBool() { 45 | return Math.random() < .5; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/components/camera/camera.ts: -------------------------------------------------------------------------------- 1 | import {Component, ViewChild, Renderer, ElementRef, Output, EventEmitter} from '@angular/core'; 2 | import {Voice} from '../../services/voice'; 3 | 4 | export let CAMERA_TYPE = { 5 | "FRONT": "facing front", 6 | "REAR": "facing back" 7 | }; 8 | 9 | @Component({ 10 | selector: 'letmesee-camera', 11 | template: ` 12 | 13 | 14 | ` 15 | }) 16 | export class CameraComponent { 17 | 18 | @ViewChild('canvas') canvas; 19 | @ViewChild('video') video; 20 | 21 | @Output('onDimensionUpdate') dimensionUpdated = new EventEmitter(); 22 | 23 | private nativeCanvas: any; 24 | 25 | private cameraConstraints = { 26 | width: { min: 1024, ideal: 1280, max: 1920 }, 27 | height: { min: 776, ideal: 720, max: 1080 } 28 | }; 29 | 30 | private videoSource; 31 | 32 | constructor( 33 | private elementRef: ElementRef, 34 | private renderer: Renderer, 35 | private voice: Voice 36 | ) { 37 | this.videoSource = { facingMode: CAMERA_TYPE.REAR }; 38 | } 39 | 40 | ngAfterViewInit() { 41 | 42 | window.URL = window.URL || (window).webkitURL; 43 | 44 | // https://developers.google.com/web/updates/2015/10/media-devices?hl=en#getusermedia 45 | navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; 46 | (window).MediaDevices = (window).MediaDevices || navigator.getUserMedia; 47 | 48 | this.nativeCanvas = this.canvas.nativeElement; 49 | let context = this.nativeCanvas.getContext('2d'); 50 | let videoNative = this.video.nativeElement; 51 | let vw, vh; 52 | 53 | if ('MediaDevices' in window || navigator.getUserMedia) { 54 | 55 | navigator.mediaDevices.enumerateDevices() 56 | .then((devices) => { 57 | return devices 58 | .filter( (device) => device.kind === 'videoinput' ); 59 | }) 60 | .then( (devices) => { 61 | 62 | navigator.getUserMedia( 63 | { video: this.figureOutWhichCameraToUse(devices) }, 64 | (stream) => videoNative.src = window.URL.createObjectURL(stream), 65 | (e) => console.log('failed', e) 66 | ); 67 | 68 | }) 69 | .catch((err) => { 70 | console.log(err.name + ": " + err.message); 71 | }); 72 | } 73 | 74 | let draw = () => { 75 | if (videoNative.paused || videoNative.ended) { 76 | return false; 77 | } 78 | context.drawImage(videoNative, 0, 0, vw, vh); 79 | window.requestAnimationFrame(draw); 80 | }; 81 | 82 | var self = this; 83 | videoNative.addEventListener('loadedmetadata', function() { 84 | vw = this.videoWidth || this.width; 85 | vh = this.videoHeight || this.height; 86 | self.nativeCanvas.width = Math.min(window.innerWidth, vw); 87 | self.nativeCanvas.height = vh; 88 | 89 | self.dimensionUpdated.emit({vw:self.nativeCanvas.width, vh}); 90 | 91 | }, false); 92 | videoNative.addEventListener('play', draw, false); 93 | } 94 | 95 | private figureOutWhichCameraToUse(devices): any { 96 | let device = devices 97 | .filter( (device) => device.label.indexOf(CAMERA_TYPE.FRONT) !== -1 ) 98 | .pop(); 99 | 100 | if(device) { 101 | return {deviceId: device.deviceId ? {exact: device.deviceId} : undefined}; 102 | } 103 | return true; 104 | } 105 | 106 | getImageAsBase64() { 107 | return this.nativeCanvas.toDataURL(); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /app/pages/home/home.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Let Me See 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/pages/home/home.scss: -------------------------------------------------------------------------------- 1 | .toolbar-title { 2 | color: color($colors, light) !important; 3 | } 4 | 5 | .card { 6 | padding: 0; 7 | line-height: 0; 8 | text-align: center; 9 | background-color: color($colors, primary); 10 | } 11 | 12 | video { 13 | display: none; 14 | } 15 | 16 | ion-card { 17 | margin: 0 auto; 18 | } 19 | -------------------------------------------------------------------------------- /app/pages/home/home.ts: -------------------------------------------------------------------------------- 1 | import {Inject, ViewChild, ElementRef, Renderer} from '@angular/core'; 2 | import {Page} from 'ionic-angular'; 3 | import {Speech} from '../../services/speech'; 4 | import {Vision, FEATURE_TYPE} from '../../services/vision'; 5 | import {Voice} from '../../services/voice'; 6 | import {Phrase, Phrases} from '../../services/phrase'; 7 | import {CameraComponent} from '../../components/camera/camera'; 8 | import {AngieComponent} from '../../components/angie/angie'; 9 | 10 | @Page({ 11 | templateUrl: 'build/pages/home/home.html', 12 | directives: [CameraComponent, AngieComponent] 13 | }) 14 | export class HomePage { 15 | 16 | @ViewChild(CameraComponent) camera: CameraComponent; 17 | @ViewChild('card') card; 18 | @ViewChild('easter') easter; 19 | 20 | private lastCommand: Function; 21 | private angieSpeaking: boolean = false; 22 | 23 | constructor( 24 | private speech: Speech, 25 | private vision: Vision, 26 | private voice: Voice, 27 | private phrase: Phrase, 28 | private elementRef: ElementRef, 29 | private renderer: Renderer 30 | ) { 31 | 32 | this.lastCommand = () => { }; 33 | } 34 | 35 | ngOnInit() { 36 | this.voice.speaking.subscribe(value => { 37 | this.angieSpeaking = value; 38 | }); 39 | } 40 | 41 | ngAfterViewInit() { 42 | 43 | this.speech 44 | .addCommands([ 45 | 'my name is :name', 46 | 'i am :name', 47 | (name) => this.voice.rememberName(name) 48 | ]) 49 | .addCommands([ 50 | 'let me see', 51 | 'show me', 52 | '(describe) what do you see', 53 | () => setTimeout(this.describeWhatISee.bind(this), 1000) 54 | ]) 55 | .addCommands([ 56 | 'how do I look', 57 | () => setTimeout(this.describeFacial.bind(this), 1000) 58 | ]) 59 | .addCommands([ 60 | 'tell me colors', 61 | 'what color is this', 62 | () => setTimeout(this.describeColor.bind(this), 1000) 63 | ]) 64 | .addCommands([ 65 | 'help', 66 | 'what should I say', 67 | () => this.voice.help() 68 | ]) 69 | .addCommands([ 70 | 'who are you', 71 | () => this.voice.whoAmI() 72 | ]) 73 | .addCommands([ 74 | 'and this', 75 | 'and now', 76 | () => this.replayLastCommand() 77 | ]) 78 | .addCommands([ 79 | '(can you) read this (for me)', 80 | 'read it', 81 | () => setTimeout(this.describeText.bind(this), 1000) 82 | ]) 83 | .addCommands([ 84 | '(a filter which is a) pipe filter', 85 | 'shy shy shy', 86 | () => this.playAudio() 87 | ]) 88 | .start(); 89 | } 90 | 91 | updateCardDimension(event) { 92 | this.renderer.setElementStyle(this.card.nativeElement, 'width', `${event.vw}px`); 93 | } 94 | 95 | describeHelp() { 96 | this.voice.help(); 97 | } 98 | 99 | private describeWhatISee() { 100 | this.lastCommand = () => { 101 | this.voice.say(`${this.phrase.get(Phrases.OK)} ${this.voice.name}. ${this.phrase.get(Phrases.LOOKUP_THINGS)}`); 102 | this.vision.process(this.camera.getImageAsBase64()).subscribe( 103 | data => this.voice.say(this.formatText(data.labels), { delay: 2000 }), 104 | err => console.error(err), 105 | () => {} 106 | ); 107 | }; 108 | 109 | this.lastCommand(); 110 | } 111 | 112 | private describeFacial() { 113 | this.lastCommand = () => { 114 | this.voice.say(`${this.phrase.get(Phrases.OK)} ${this.voice.name}. ${this.phrase.get(Phrases.LOOKUP_FACE)}`); 115 | this.vision.process(this.camera.getImageAsBase64(), FEATURE_TYPE.FACE_DETECTION) 116 | .subscribe( 117 | data => this.voice.say(this.formatText(data.face), { delay: 2000 }), 118 | err => console.error(err), 119 | () => {} 120 | ); 121 | }; 122 | 123 | this.lastCommand(); 124 | } 125 | 126 | private describeColor() { 127 | this.lastCommand = () => { 128 | this.voice.say(`${this.phrase.get(Phrases.OK)} you need colors. ${this.phrase.get(Phrases.LOOKUP_COLOR)} ${this.voice.name}.`); 129 | this.vision.process(this.camera.getImageAsBase64(), FEATURE_TYPE.IMAGE_PROPERTIES) 130 | .subscribe( 131 | data => this.voice.say(`Well ${this.voice.name}, I see mostly ${data.color}`, { delay: 2000 }), 132 | err => console.error(err), 133 | () => {} 134 | ); 135 | }; 136 | 137 | this.lastCommand(); 138 | } 139 | 140 | private describeText() { 141 | this.lastCommand = () => { 142 | this.voice.say(`${this.phrase.get(Phrases.OK)}. ${this.phrase.get(Phrases.LOOKUP_TEXT)} ${this.voice.name}.`); 143 | this.vision.process(this.camera.getImageAsBase64(), FEATURE_TYPE.TEXT_DETECTION) 144 | .subscribe( 145 | data => this.voice.say(this.formatText(data.text, 'Here is the extracted text:'), { delay: 2000 }), 146 | err => console.error(err), 147 | () => {} 148 | ); 149 | }; 150 | 151 | this.lastCommand(); 152 | } 153 | 154 | private replayLastCommand() { 155 | this.lastCommand(); 156 | } 157 | 158 | private formatText(data: string[] = [], defaultText: string = 'I see'): string { 159 | let text = `Well ${this.voice.name}, ${defaultText} ${data.join(', ')}`; 160 | if (data.length === 0) { 161 | text = `Sorry ${this.voice.name}! I could not recognize what I see.`; 162 | } 163 | return text; 164 | } 165 | 166 | private playAudio() { 167 | this.easter.nativeElement.play(); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /app/services/colors-dictionary.ts: -------------------------------------------------------------------------------- 1 | 2 | // dictionary names inspired by http://chir.ag/projects/ntc/ntc.js 3 | 4 | export const COLORS = { 5 | "000000": "Black", 6 | "000080": "Navy Blue", 7 | "0000C8": "Dark Blue", 8 | "0000FF": "Blue", 9 | "003366": "Midnight Blue", 10 | "003532": "Deep Teal", 11 | "008080": "Teal", 12 | "009DC4": "Pacific Blue", 13 | "00CC99": "Caribbean Green", 14 | "00FF00": "Green", 15 | "00FF7F": "Spring Green", 16 | "010D1A": "Blue Charcoal", 17 | "01361C": "Cardin Green", 18 | "01371A": "County Green", 19 | "013E62": "Astronaut Blue", 20 | "013F6A": "Regal Blue", 21 | "016D39": "Fun Green", 22 | "01796F": "Pine Green", 23 | "017987": "Blue Lagoon", 24 | "01A368": "Green Haze", 25 | "02402C": "Sherwood Green", 26 | "02478E": "Congress Blue", 27 | "026395": "Bahama Blue", 28 | "032B52": "Green Vogue", 29 | "041322": "Black Pearl", 30 | "042E4C": "Blue Whale", 31 | "044259": "Teal Blue", 32 | "051657": "Gulf Blue", 33 | "055989": "Venice Blue", 34 | "08E8DE": "Bright Turquoise", 35 | "09230F": "Palm Green", 36 | "09255D": "Madison", 37 | "093624": "Bottle Green", 38 | "095859": "Deep Sea Green", 39 | "0C8990": "Blue Chill", 40 | "0D0332": "Black Rock", 41 | "13264D": "Blue Zodiac", 42 | "1450AA": "Tory Blue", 43 | "161D10": "Hunter Green", 44 | "16322C": "Timber Green", 45 | "163531": "Gable Green", 46 | "175579": "Chathams Blue", 47 | "182D09": "Deep Forest Green", 48 | "193751": "Nile Blue", 49 | "1959A8": "Fun Blue", 50 | "1C1E13": "Rangoon Green", 51 | "1C39BB": "Persian Blue", 52 | "1D6142": "Green Pea", 53 | "1E433C": "Te Papa Green", 54 | "20208D": "Jacksons Purple", 55 | "220878": "Deep Blue", 56 | "228B22": "Forest Green", 57 | "240A40": "Violet", 58 | "242E16": "Black Olive", 59 | "251607": "Graphite", 60 | "251706": "Cannon Black", 61 | "290C5E": "Violent Violet", 62 | "29AB87": "Jungle Green", 63 | "2A380B": "Turtle Green", 64 | "2A52BE": "Cerulean Blue", 65 | "2B0202": "Sepia Black", 66 | "2C0E8C": "Blue Gem", 67 | "2E8B57": "Sea Green", 68 | "301F1E": "Cocoa Brown", 69 | "370202": "Chocolate", 70 | "3C4151": "Bright Gray", 71 | "3F5D53": "Mineral Green", 72 | "4169E1": "Royal Blue", 73 | "41AA78": "Ocean Green", 74 | "436A0D": "Green Leaf", 75 | "45B1E8": "Picton Blue", 76 | "480404": "Rustic Red", 77 | "483131": "Woody Brown", 78 | "495400": "Verdun Green", 79 | "4F7942": "Fern Green", 80 | "516E3D": "Chalet Green", 81 | "56B4BE": "Fountain Blue", 82 | "593737": "Congo Brown", 83 | "5D1E0F": "Redwood", 84 | "5F5F6E": "Mid Gray", 85 | "5F6672": "Shuttle Gray", 86 | "61845F": "Glade Green", 87 | "6456B7": "Blue Violet", 88 | "6495ED": "Cornflower Blue", 89 | "65000B": "Rosewood", 90 | "651A14": "Cherrywood", 91 | "660099": "Purple", 92 | "66023C": "Tyrian Purple", 93 | "66FF00": "Bright Green", 94 | "676662": "Ironside Gray", 95 | "678975": "Viridian Green", 96 | "6B3FA0": "Royal Purple", 97 | "6CDAE7": "Turquoise Blue", 98 | "71D9E2": "Aquamarine Blue", 99 | "72010F": "Venetian Red", 100 | "76D7EA": "Sky Blue", 101 | "77DD77": "Pastel Green", 102 | "78866B": "Camouflage Green", 103 | "7A58C1": "Fuchsia Blue", 104 | "800000": "Maroon", 105 | "80341F": "Red Robin", 106 | "803790": "Vivid Violet", 107 | "8AB9F1": "Jordy Blue", 108 | "8B8680": "Natural Gray", 109 | "8D8974": "Granite Green", 110 | "8DA8CC": "Polo Blue", 111 | "9370DB": "Medium Purple", 112 | "964B00": "Brown", 113 | "967059": "Leather", 114 | "967BB6": "Lavender Purple", 115 | "991199": "Violet Eggplant", 116 | "A69279": "Donkey Brown", 117 | "A9A491": "Gray Olive", 118 | "A9ACB6": "Aluminium", 119 | "A9B2C3": "Cadet Blue", 120 | "ACB78E": "Swamp Green", 121 | "ADFF2F": "Green Yellow", 122 | "AE4560": "Hippie Pink", 123 | "AF593E": "Brown Rust", 124 | "B10000": "Bright Red", 125 | "B5B35C": "Olive Green", 126 | "B6B095": "Heathered Gray", 127 | "B81104": "Milano Red", 128 | "B8C1B1": "Green Spring", 129 | "BB3385": "Medium Red Violet", 130 | "BDB1A8": "Silk", 131 | "C154C1": "Fuchsia Pink", 132 | "C5E17A": "Yellow Green", 133 | "C62D42": "Brick Red", 134 | "C71585": "Red Violet", 135 | "C9B93B": "Earls Green", 136 | "C9C0BB": "Silver Rust", 137 | "C9FFE5": "Aero Blue", 138 | "CBCAB6": "Foggy Gray", 139 | "E2F3EC": "Apple Green", 140 | "E8EBE0": "Green White", 141 | "ED9121": "Carrot Orange", 142 | "F5F5DC": "Beige", 143 | "FEFCED": "Orange White", 144 | "FF0000": "Red", 145 | "FF3F34": "Red Orange", 146 | "FF681F": "Orange", 147 | "FFAE42": "Yellow Orange", 148 | "FFBF00": "Amber", 149 | "FFC0CB": "Pink", 150 | "FFD700": "Gold", 151 | "FFEFD5": "Papaya Whip", 152 | "FFEFEC": "Fair Pink", 153 | "FFF0DB": "Peach Cream", 154 | "FFF6F5": "Rose White", 155 | "FFF8D1": "Baja White", 156 | "FFFDD0": "Cream", 157 | "FFFF00": "Yellow", 158 | "FFFFFF": "White" 159 | }; 160 | -------------------------------------------------------------------------------- /app/services/phrase.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | 3 | export enum Phrases { 4 | OK, GREETING, NAME, HELP, 5 | LOOKUP_THINGS, LOOKUP_COLOR, LOOKUP_FACE, LOOKUP_TEXT 6 | } 7 | 8 | const DICTIONARY = { 9 | "OK": [ 10 | 'Ok', 'I got it', 'Gotcha' 11 | ], 12 | "GREETING": [ 13 | 'Hi', 'Hello', 'Welcome' 14 | ], 15 | "NAME": [ 16 | 'What is your name?', 'Who are you?' 17 | ], 18 | "HELP": [ 19 | 'How can I help you?', 'How can I assist you?', 'Can I help?', 'Do you need help?' 20 | ], 21 | "LOOKUP_THINGS": [ 22 | 'Let me check that for you.', 'Let me search that for you.', 'Let me find that for you.', 'Let me analyse it for you.' 23 | ], 24 | "LOOKUP_COLOR": [ 25 | 'Let me analyse them.', 'Let me identify them.', 'Let me collect them.' 26 | ], 27 | "LOOKUP_FACE": [ 28 | 'Let me describe your face.', 'Let me see how you feel.' 29 | ], 30 | "LOOKUP_TEXT": [ 31 | 'Let me read this for you.', 'Let me spell this for you.' 32 | ] 33 | } 34 | 35 | @Injectable() 36 | export class Phrase { 37 | 38 | constructor() { } 39 | 40 | public get(phrase: Phrases) { 41 | let phrases = DICTIONARY[Phrases[phrase]]; 42 | return phrases[Math.floor(Math.random() * phrases.length)]; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/services/speech.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import * as annyang from 'annyang'; 3 | 4 | @Injectable() 5 | export class Speech { 6 | 7 | private commands: any[]; 8 | 9 | constructor() { 10 | this.commands = []; 11 | } 12 | 13 | public addCommands(commands: any[]) { 14 | let action = commands.pop(); 15 | 16 | // @todo dynamic Object keys are not working with TS 1.8.10! 17 | //commands.forEach( phrase => this.commands.push({ [phrase]: action }) ); 18 | 19 | commands.forEach( phrase => { 20 | let o = {}; 21 | o[phrase] = action; 22 | this.commands.push(o); 23 | }); 24 | 25 | return this; 26 | 27 | } 28 | 29 | public start() { 30 | 31 | if(annyang) { 32 | this.commands.forEach(annyang.addCommands); 33 | annyang.start({ continuous: true }); 34 | } 35 | else { 36 | console.error('speech recognition is not available.'); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/services/vision.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, EventEmitter } from '@angular/core'; 2 | import { Http, Headers } from '@angular/http'; 3 | import { COLORS } from './colors-dictionary'; 4 | import 'rxjs/add/operator/map'; 5 | 6 | interface IRGBColor { 7 | red: number; 8 | green: number; 9 | blue: number; 10 | } 11 | 12 | export const FEATURE_TYPE = { 13 | TYPE_UNSPECIFIED: 'TYPE_UNSPECIFIED', 14 | FACE_DETECTION: 'FACE_DETECTION', 15 | LANDMARK_DETECTION: 'LANDMARK_DETECTION', 16 | LOGO_DETECTION: 'LOGO_DETECTION', 17 | LABEL_DETECTION: 'LABEL_DETECTION', 18 | TEXT_DETECTION: 'TEXT_DETECTION', 19 | SAFE_SEARCH_DETECTION: 'SAFE_SEARCH_DETECTION', 20 | IMAGE_PROPERTIES: 'IMAGE_PROPERTIES' 21 | }; 22 | 23 | @Injectable() 24 | export class Vision { 25 | private VISION_ENDPOINT = 'https://vision.googleapis.com/v1/images:annotate?key={{YOUR_KEY}}'; 26 | 27 | constructor(private http: Http) {} 28 | 29 | /** 30 | * Process the user's query. 31 | * Available queries: 32 | * - LABEL_DETECTION : for generic label extraction (default) 33 | * - FACE_DETECTION : for facial expression 34 | * - TEXT_DETECTION : for OCR text 35 | * - IMAGE_PROPERTIES : for dominant color extraction 36 | */ 37 | process(base64: string, feature: string = FEATURE_TYPE.LABEL_DETECTION) { 38 | let request: any = { 39 | requests: [ 40 | { 41 | image: { 42 | content: base64.replace(/data:image\/(jpeg|png);base64,/g, '') 43 | }, 44 | features: [ 45 | { 46 | type: feature, 47 | maxResults: 200 48 | } 49 | ] 50 | } 51 | ] 52 | }; 53 | return this.post(request); 54 | } 55 | 56 | /** 57 | * Send the request to the Google Vision API endpoint. 58 | */ 59 | private post(request: any) { 60 | let headers = new Headers(); 61 | headers.append('Content-Type', 'application/json'); 62 | 63 | return this.http 64 | .post(this.VISION_ENDPOINT, JSON.stringify(request), headers) 65 | .map(res => res.json()) 66 | .map(res => this.processMetadata(res)); 67 | } 68 | 69 | /** 70 | * Process the response result from the Vision endpoint. 71 | */ 72 | private processMetadata(data: any): any[] | any { 73 | data.responses = data.responses || {}; 74 | if (Array.isArray(data.responses)) { 75 | data.responses = data.responses.pop(); 76 | } 77 | 78 | if (data.responses.labelAnnotations) { 79 | let labels = []; 80 | (data.responses.labelAnnotations || []).forEach(lbl => { 81 | labels.push(lbl.description); 82 | }); 83 | return { labels }; 84 | } 85 | 86 | if (data.responses.faceAnnotations) { 87 | let face = []; 88 | (data.responses.faceAnnotations || []).forEach(expression => { 89 | for (var exp in expression) { 90 | if (exp.indexOf('Likelihood') !== -1) { 91 | face.push(exp.replace('Likelihood', '')); 92 | } 93 | } 94 | }); 95 | return { face }; 96 | } 97 | 98 | if (data.responses.imagePropertiesAnnotation) { 99 | let colorResponse = data.responses.imagePropertiesAnnotation.dominantColors.colors 100 | .sort((colorA, colorB) => colorA.score > colorB.score) 101 | .pop(); 102 | let color: IRGBColor = colorResponse.color; 103 | return { color: this.findNearestColorName(color) }; 104 | } 105 | 106 | if (data.responses.textAnnotations) { 107 | let text = (data.responses.textAnnotations || []).shift(); 108 | return { text: [text.description] }; 109 | } 110 | 111 | return []; 112 | } 113 | 114 | /** 115 | * Find the nearest color name based on the RGB color extracted from the image. 116 | */ 117 | private findNearestColorName(color: IRGBColor): string { 118 | return COLORS[ 119 | Object.keys(COLORS) 120 | .map((arrayColor, key, arr) => { 121 | return { color: arr[key], distance: this.colorDistance(color, this.hexToRgb(arrayColor)) }; 122 | }) 123 | .sort((a, b) => (a.distance > b.distance ? -1 : 1)) 124 | .pop().color 125 | ]; 126 | } 127 | 128 | /** 129 | * Convert HEX color to RGB values 130 | */ 131 | private hexToRgb(hex: string): IRGBColor { 132 | return { 133 | red: parseInt(hex.substr(0, 2), 16), 134 | green: parseInt(hex.substr(2, 2), 16), 135 | blue: parseInt(hex.substr(4, 2), 16) 136 | }; 137 | } 138 | 139 | /** 140 | * Compute the distance between two RGB colors 141 | */ 142 | private colorDistance(left: IRGBColor, right: IRGBColor): number { 143 | return Math.abs(left.red - right.red) + Math.abs(left.green - right.green) + Math.abs(left.blue - right.blue); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /app/services/voice.ts: -------------------------------------------------------------------------------- 1 | import {Injectable, EventEmitter} from '@angular/core'; 2 | import * as annyang from 'annyang'; 3 | import {Phrase, Phrases} from './phrase'; 4 | 5 | const SPEECH_VOICE = 'US English Female'; 6 | 7 | declare var responsiveVoice; 8 | 9 | @Injectable() 10 | export class Voice { 11 | 12 | private rv: any = null; 13 | private isSpeaking: boolean = false; 14 | private q = []; 15 | 16 | public speaking = new EventEmitter(); 17 | public name = ''; 18 | 19 | constructor( 20 | private phrase: Phrase 21 | ) { 22 | this.q = []; 23 | 24 | if ('responsiveVoice' in window) { 25 | this.rv = responsiveVoice; 26 | } 27 | } 28 | 29 | start() { 30 | this.rv.OnVoiceReady = () => { 31 | this.rv.setDefaultVoice(SPEECH_VOICE); 32 | this.say(`${this.phrase.get(Phrases.GREETING)}. ${this.phrase.get(Phrases.HELP)}`, { delay: 1000 }); 33 | this.say(`${this.phrase.get(Phrases.NAME)}`, { delay: 4000 }); 34 | 35 | this.q.forEach( (text) => this.say(text, { delay: 8000}) ); 36 | this.q = []; 37 | 38 | }; 39 | } 40 | 41 | /** 42 | * push some text to be spoken later. 43 | */ 44 | sayDelay(text: string) { 45 | this.q.push(text); 46 | } 47 | 48 | /** 49 | * text to voice. 50 | */ 51 | say(text: string, options: any = {}) { 52 | options.delay = options.delay || 0; 53 | setTimeout(() => { 54 | this.rv.speak(text, SPEECH_VOICE, { 55 | onstart: () => { 56 | this.isSpeaking = true; 57 | this.speaking.emit(true); 58 | }, 59 | onend: () => { 60 | this.isSpeaking = false; 61 | this.speaking.emit(false); 62 | } 63 | }); 64 | }, options.delay); 65 | } 66 | 67 | help() { 68 | if(this.isSpeaking === false) { 69 | this.say(` 70 | Here are the commands I can understand: 71 | 72 | 'my name is ', 73 | 74 | 'let me see', 'show me', '(describe) what do you see', 75 | 76 | 'how do I look', 77 | 78 | 'tell me colors', 'what color is this', 79 | 80 | 'help', 'what should I say', 81 | 82 | 'who are you', 83 | 84 | '(can you) read this (for me)', 'read it', 85 | 86 | also, you can say 87 | 88 | 'and this', 'and now', 89 | 90 | in order to run the last query. 91 | `); 92 | } 93 | } 94 | 95 | whoAmI() { 96 | this.say(`You are welcome ${name}, I am your assistant Angie, and I am here to help you see the world.`); 97 | } 98 | 99 | rememberName(name?) { 100 | this.name = name; 101 | this.say(`${this.phrase.get(Phrases.GREETING)} ${this.name}, how can I help you`); 102 | } 103 | 104 | sorry(blah?) { 105 | this.say(`Sorry ${this.name}, I don't understand ${blah}. If you are lost, just say "help"`); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /app/theme/app.core.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | 4 | // App Shared Imports 5 | // -------------------------------------------------- 6 | // These are the imports which make up the design of this app. 7 | // By default each design mode includes these shared imports. 8 | // App Shared Sass variables belong in app.variables.scss. 9 | 10 | @import '../pages/home/home'; 11 | 12 | body, html {background-color: #2C1B31;} 13 | -------------------------------------------------------------------------------- /app/theme/app.ios.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | 4 | // App Shared Variables 5 | // -------------------------------------------------- 6 | // Shared Sass variables go in the app.variables.scss file 7 | @import "app.variables"; 8 | 9 | 10 | // App iOS Variables 11 | // -------------------------------------------------- 12 | // iOS only Sass variables can go here 13 | 14 | 15 | // Ionic iOS Sass 16 | // -------------------------------------------------- 17 | // Custom App variables must be declared before importing Ionic. 18 | // Ionic will use its default values when a custom variable isn't provided. 19 | @import "ionic.ios"; 20 | 21 | 22 | // App Shared Sass 23 | // -------------------------------------------------- 24 | // All Sass files that make up this app goes into the app.core.scss file. 25 | // For simpler CSS overrides, custom app CSS must come after Ionic's CSS. 26 | @import "app.core"; 27 | 28 | 29 | // App iOS Only Sass 30 | // -------------------------------------------------- 31 | // CSS that should only apply to the iOS app 32 | -------------------------------------------------------------------------------- /app/theme/app.md.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | 4 | // App Shared Variables 5 | // -------------------------------------------------- 6 | // Shared Sass variables go in the app.variables.scss file 7 | @import "app.variables"; 8 | 9 | 10 | // App Material Design Variables 11 | // -------------------------------------------------- 12 | // Material Design only Sass variables can go here 13 | 14 | 15 | // Ionic Material Design Sass 16 | // -------------------------------------------------- 17 | // Custom App variables must be declared before importing Ionic. 18 | // Ionic will use its default values when a custom variable isn't provided. 19 | @import "ionic.md"; 20 | 21 | 22 | // App Shared Sass 23 | // -------------------------------------------------- 24 | // All Sass files that make up this app goes into the app.core.scss file. 25 | // For simpler CSS overrides, custom app CSS must come after Ionic's CSS. 26 | @import "app.core"; 27 | 28 | 29 | // App Material Design Only Sass 30 | // -------------------------------------------------- 31 | // CSS that should only apply to the Material Design app 32 | -------------------------------------------------------------------------------- /app/theme/app.variables.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | // Ionic Shared Functions 4 | // -------------------------------------------------- 5 | // Makes Ionic Sass functions available to your App 6 | 7 | @import "globals.core"; 8 | 9 | // App Shared Variables 10 | // -------------------------------------------------- 11 | // To customize the look and feel of this app, you can override 12 | // the Sass variables found in Ionic's source scss files. Setting 13 | // variables before Ionic's Sass will use these variables rather than 14 | // Ionic's default Sass variable values. App Shared Sass imports belong 15 | // in the app.core.scss file and not this file. Sass variables specific 16 | // to the mode belong in either the app.ios.scss or app.md.scss files. 17 | 18 | 19 | // App Shared Color Variables 20 | // -------------------------------------------------- 21 | // It's highly recommended to change the default colors 22 | // to match your app's branding. Ionic uses a Sass map of 23 | // colors so you can add, rename and remove colors as needed. 24 | // The "primary" color is the only required color in the map. 25 | // Both iOS and MD colors can be further customized if colors 26 | // are different per mode. 27 | 28 | $colors: ( 29 | primary: #387ef5, 30 | secondary: #32db64, 31 | danger: #f53d3d, 32 | light: #f4f4f4, 33 | dark: #222, 34 | favorite: #69BB7B 35 | ); 36 | -------------------------------------------------------------------------------- /app/theme/app.wp.scss: -------------------------------------------------------------------------------- 1 | // http://ionicframework.com/docs/v2/theming/ 2 | 3 | 4 | // App Shared Variables 5 | // -------------------------------------------------- 6 | // Shared Sass variables go in the app.variables.scss file 7 | @import "app.variables"; 8 | 9 | 10 | // App Windows Variables 11 | // -------------------------------------------------- 12 | // Windows only Sass variables can go here 13 | 14 | 15 | // Ionic Windows Sass 16 | // -------------------------------------------------- 17 | // Custom App variables must be declared before importing Ionic. 18 | // Ionic will use its default values when a custom variable isn't provided. 19 | @import "ionic.wp"; 20 | 21 | 22 | // App Shared Sass 23 | // -------------------------------------------------- 24 | // All Sass files that make up this app goes into the app.core.scss file. 25 | // For simpler CSS overrides, custom app CSS must come after Ionic's CSS. 26 | @import "app.core"; 27 | 28 | 29 | // App Windows Only Sass 30 | // -------------------------------------------------- 31 | // CSS that should only apply to the Windows app 32 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 5.10.1 4 | 5 | test: 6 | override: 7 | - echo "test" 8 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | LetMeSee 4 | Let blind people see through this application 5 | Wassim Chegham 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "www", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | gulpWatch = require('gulp-watch'), 3 | gulpReplace = require('gulp-replace'), 4 | del = require('del'), 5 | runSequence = require('run-sequence'), 6 | argv = process.argv; 7 | 8 | 9 | /** 10 | * Ionic hooks 11 | * Add ':before' or ':after' to any Ionic project command name to run the specified 12 | * tasks before or after the command. 13 | */ 14 | gulp.task('serve:before', ['watch']); 15 | gulp.task('emulate:before', ['build']); 16 | gulp.task('deploy:before', ['build']); 17 | gulp.task('build:before', ['build']); 18 | gulp.task('build:after', ['sw']); 19 | 20 | // we want to 'watch' when livereloading 21 | var shouldWatch = argv.indexOf('-l') > -1 || argv.indexOf('--livereload') > -1; 22 | gulp.task('run:before', [shouldWatch ? 'watch' : 'build']); 23 | 24 | /** 25 | * Ionic Gulp tasks, for more information on each see 26 | * https://github.com/driftyco/ionic-gulp-tasks 27 | * 28 | * Using these will allow you to stay up to date if the default Ionic 2 build 29 | * changes, but you are of course welcome (and encouraged) to customize your 30 | * build however you see fit. 31 | */ 32 | var buildBrowserify = require('ionic-gulp-browserify-typescript'); 33 | var buildSass = require('ionic-gulp-sass-build'); 34 | var copyHTML = require('ionic-gulp-html-copy'); 35 | var copyFonts = require('ionic-gulp-fonts-copy'); 36 | var copyScripts = require('ionic-gulp-scripts-copy'); 37 | var tslint = require('ionic-gulp-tslint'); 38 | 39 | var isRelease = argv.indexOf('--release') > -1; 40 | 41 | gulp.task('watch', ['clean'], function(done){ 42 | runSequence( 43 | ['sass', 'html', 'fonts', 'scripts'], 44 | 'sw', 45 | function(){ 46 | gulpWatch('app/**/*.scss', function(){ gulp.start('sass'); }); 47 | gulpWatch('app/**/*.html', function(){ gulp.start('html'); }); 48 | buildBrowserify({ watch: true }).on('end', done); 49 | } 50 | ); 51 | }); 52 | 53 | gulp.task('build', ['clean'], function(done){ 54 | runSequence( 55 | ['sass', 'html', 'fonts', 'scripts'], 56 | function(){ 57 | buildBrowserify({ 58 | minify: isRelease, 59 | browserifyOptions: { 60 | debug: !isRelease 61 | }, 62 | uglifyOptions: { 63 | mangle: false 64 | } 65 | }).on('end', done); 66 | } 67 | ); 68 | }); 69 | 70 | gulp.task('version', function(callback) { 71 | 72 | // require('./package.json') caches files so it won't help us here. 73 | var version = JSON.parse(require('fs').readFileSync('./package.json')).version; 74 | console.log(version); 75 | 76 | return gulp.src('www/index.html') 77 | .pipe(gulpReplace( 78 | /v(.*?)<\/span>/, 79 | 'v'+version+'' 80 | )) 81 | .pipe(gulp.dest('www/')) 82 | }); 83 | 84 | gulp.task('sw', function(callback) { 85 | var path = require('path'); 86 | var swPrecache = require('sw-precache'); 87 | var rootDir = 'www'; 88 | var options = require('./sw-precache-config.json'); 89 | options.ignoreUrlParametersMatching = [/./]; 90 | swPrecache.write(path.join(rootDir, 'sw.js'), options, callback); 91 | }); 92 | 93 | gulp.task('sass', buildSass); 94 | gulp.task('html', copyHTML); 95 | gulp.task('fonts', copyFonts); 96 | gulp.task('scripts', copyScripts); 97 | gulp.task('clean', function(){ 98 | return del('www/build'); 99 | }); 100 | gulp.task('lint', tslint); 101 | -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | 21 | # Cordova Hooks 22 | 23 | Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. Hook scripts could be defined by adding them to the special predefined folder (`/hooks`) or via configuration files (`config.xml` and `plugin.xml`) and run serially in the following order: 24 | * Application hooks from `/hooks`; 25 | * Application hooks from `config.xml`; 26 | * Plugin hooks from `plugins/.../plugin.xml`. 27 | 28 | __Remember__: Make your scripts executable. 29 | 30 | __Note__: `.cordova/hooks` directory is also supported for backward compatibility, but we don't recommend using it as it is deprecated. 31 | 32 | ## Supported hook types 33 | The following hook types are supported: 34 | 35 | after_build/ 36 | after_compile/ 37 | after_docs/ 38 | after_emulate/ 39 | after_platform_add/ 40 | after_platform_rm/ 41 | after_platform_ls/ 42 | after_plugin_add/ 43 | after_plugin_ls/ 44 | after_plugin_rm/ 45 | after_plugin_search/ 46 | after_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed 47 | after_prepare/ 48 | after_run/ 49 | after_serve/ 50 | before_build/ 51 | before_compile/ 52 | before_docs/ 53 | before_emulate/ 54 | before_platform_add/ 55 | before_platform_rm/ 56 | before_platform_ls/ 57 | before_plugin_add/ 58 | before_plugin_ls/ 59 | before_plugin_rm/ 60 | before_plugin_search/ 61 | before_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed 62 | before_plugin_uninstall/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being uninstalled 63 | before_prepare/ 64 | before_run/ 65 | before_serve/ 66 | pre_package/ <-- Windows 8 and Windows Phone only. 67 | 68 | ## Ways to define hooks 69 | ### Via '/hooks' directory 70 | To execute custom action when corresponding hook type is fired, use hook type as a name for a subfolder inside 'hooks' directory and place you script file here, for example: 71 | 72 | # script file will be automatically executed after each build 73 | hooks/after_build/after_build_custom_action.js 74 | 75 | 76 | ### Config.xml 77 | 78 | Hooks can be defined in project's `config.xml` using `` elements, for example: 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ... 89 | 90 | 91 | 92 | 93 | 94 | 95 | ... 96 | 97 | 98 | ### Plugin hooks (plugin.xml) 99 | 100 | As a plugin developer you can define hook scripts using `` elements in a `plugin.xml` like that: 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | ... 109 | 110 | 111 | `before_plugin_install`, `after_plugin_install`, `before_plugin_uninstall` plugin hooks will be fired exclusively for the plugin being installed/uninstalled. 112 | 113 | ## Script Interface 114 | 115 | ### Javascript 116 | 117 | If you are writing hooks in Javascript you should use the following module definition: 118 | ```javascript 119 | module.exports = function(context) { 120 | ... 121 | } 122 | ``` 123 | 124 | You can make your scipts async using Q: 125 | ```javascript 126 | module.exports = function(context) { 127 | var Q = context.requireCordovaModule('q'); 128 | var deferral = new Q.defer(); 129 | 130 | setTimeout(function(){ 131 | console.log('hook.js>> end'); 132 | deferral.resolve(); 133 | }, 1000); 134 | 135 | return deferral.promise; 136 | } 137 | ``` 138 | 139 | `context` object contains hook type, executed script full path, hook options, command-line arguments passed to Cordova and top-level "cordova" object: 140 | ```json 141 | { 142 | "hook": "before_plugin_install", 143 | "scriptLocation": "c:\\script\\full\\path\\appBeforePluginInstall.js", 144 | "cmdLine": "The\\exact\\command\\cordova\\run\\with arguments", 145 | "opts": { 146 | "projectRoot":"C:\\path\\to\\the\\project", 147 | "cordova": { 148 | "platforms": ["wp8"], 149 | "plugins": ["com.plugin.withhooks"], 150 | "version": "0.21.7-dev" 151 | }, 152 | "plugin": { 153 | "id": "com.plugin.withhooks", 154 | "pluginInfo": { 155 | ... 156 | }, 157 | "platform": "wp8", 158 | "dir": "C:\\path\\to\\the\\project\\plugins\\com.plugin.withhooks" 159 | } 160 | }, 161 | "cordova": {...} 162 | } 163 | 164 | ``` 165 | `context.opts.plugin` object will only be passed to plugin hooks scripts. 166 | 167 | You can also require additional Cordova modules in your script using `context.requireCordovaModule` in the following way: 168 | ```javascript 169 | var Q = context.requireCordovaModule('q'); 170 | ``` 171 | 172 | __Note__: new module loader script interface is used for the `.js` files defined via `config.xml` or `plugin.xml` only. 173 | For compatibility reasons hook files specified via `/hooks` folders are run via Node child_process spawn, see 'Non-javascript' section below. 174 | 175 | ### Non-javascript 176 | 177 | Non-javascript scripts are run via Node child_process spawn from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables: 178 | 179 | * CORDOVA_VERSION - The version of the Cordova-CLI. 180 | * CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios). 181 | * CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer) 182 | * CORDOVA_HOOK - Path to the hook that is being executed. 183 | * CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate) 184 | 185 | If a script returns a non-zero exit code, then the parent cordova command will be aborted. 186 | 187 | ## Writing hooks 188 | 189 | We highly recommend writing your hooks using Node.js so that they are 190 | cross-platform. Some good examples are shown here: 191 | 192 | [http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/) 193 | 194 | Also, note that even if you are working on Windows, and in case your hook scripts aren't bat files (which is recommended, if you want your scripts to work in non-Windows operating systems) Cordova CLI will expect a shebang line as the first line for it to know the interpreter it needs to use to launch the script. The shebang line should match the following example: 195 | 196 | #!/usr/bin/env [name_of_interpreter_executable] 197 | -------------------------------------------------------------------------------- /hooks/after_prepare/010_add_platform_class.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Add Platform Class 4 | // v1.0 5 | // Automatically adds the platform class to the body tag 6 | // after the `prepare` command. By placing the platform CSS classes 7 | // directly in the HTML built for the platform, it speeds up 8 | // rendering the correct layout/style for the specific platform 9 | // instead of waiting for the JS to figure out the correct classes. 10 | 11 | var fs = require('fs'); 12 | var path = require('path'); 13 | 14 | var rootdir = process.argv[2]; 15 | 16 | function addPlatformBodyTag(indexPath, platform) { 17 | // add the platform class to the body tag 18 | try { 19 | var platformClass = 'platform-' + platform; 20 | var cordovaClass = 'platform-cordova platform-webview'; 21 | 22 | var html = fs.readFileSync(indexPath, 'utf8'); 23 | 24 | var bodyTag = findBodyTag(html); 25 | if(!bodyTag) return; // no opening body tag, something's wrong 26 | 27 | if(bodyTag.indexOf(platformClass) > -1) return; // already added 28 | 29 | var newBodyTag = bodyTag; 30 | 31 | var classAttr = findClassAttr(bodyTag); 32 | if(classAttr) { 33 | // body tag has existing class attribute, add the classname 34 | var endingQuote = classAttr.substring(classAttr.length-1); 35 | var newClassAttr = classAttr.substring(0, classAttr.length-1); 36 | newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote; 37 | newBodyTag = bodyTag.replace(classAttr, newClassAttr); 38 | 39 | } else { 40 | // add class attribute to the body tag 41 | newBodyTag = bodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">'); 42 | } 43 | 44 | html = html.replace(bodyTag, newBodyTag); 45 | 46 | fs.writeFileSync(indexPath, html, 'utf8'); 47 | 48 | process.stdout.write('add to body class: ' + platformClass + '\n'); 49 | } catch(e) { 50 | process.stdout.write(e); 51 | } 52 | } 53 | 54 | function findBodyTag(html) { 55 | // get the body tag 56 | try{ 57 | return html.match(/])(.*?)>/gi)[0]; 58 | }catch(e){} 59 | } 60 | 61 | function findClassAttr(bodyTag) { 62 | // get the body tag's class attribute 63 | try{ 64 | return bodyTag.match(/ class=["|'](.*?)["|']/gi)[0]; 65 | }catch(e){} 66 | } 67 | 68 | if (rootdir) { 69 | 70 | // go through each of the platform directories that have been prepared 71 | var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []); 72 | 73 | for(var x=0; x 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /typings/browser/ambient/es6-shim/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/es6-shim/es6-shim.d.ts 3 | // Type definitions for es6-shim v0.31.2 4 | // Project: https://github.com/paulmillr/es6-shim 5 | // Definitions by: Ron Buckton 6 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 7 | 8 | declare type PropertyKey = string | number | symbol; 9 | 10 | interface IteratorResult { 11 | done: boolean; 12 | value?: T; 13 | } 14 | 15 | interface IterableShim { 16 | /** 17 | * Shim for an ES6 iterable. Not intended for direct use by user code. 18 | */ 19 | "_es6-shim iterator_"(): Iterator; 20 | } 21 | 22 | interface Iterator { 23 | next(value?: any): IteratorResult; 24 | return?(value?: any): IteratorResult; 25 | throw?(e?: any): IteratorResult; 26 | } 27 | 28 | interface IterableIteratorShim extends IterableShim, Iterator { 29 | /** 30 | * Shim for an ES6 iterable iterator. Not intended for direct use by user code. 31 | */ 32 | "_es6-shim iterator_"(): IterableIteratorShim; 33 | } 34 | 35 | interface StringConstructor { 36 | /** 37 | * Return the String value whose elements are, in order, the elements in the List elements. 38 | * If length is 0, the empty string is returned. 39 | */ 40 | fromCodePoint(...codePoints: number[]): string; 41 | 42 | /** 43 | * String.raw is intended for use as a tag function of a Tagged Template String. When called 44 | * as such the first argument will be a well formed template call site object and the rest 45 | * parameter will contain the substitution values. 46 | * @param template A well-formed template string call site representation. 47 | * @param substitutions A set of substitution values. 48 | */ 49 | raw(template: TemplateStringsArray, ...substitutions: any[]): string; 50 | } 51 | 52 | interface String { 53 | /** 54 | * Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point 55 | * value of the UTF-16 encoded code point starting at the string element at position pos in 56 | * the String resulting from converting this object to a String. 57 | * If there is no element at that position, the result is undefined. 58 | * If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos. 59 | */ 60 | codePointAt(pos: number): number; 61 | 62 | /** 63 | * Returns true if searchString appears as a substring of the result of converting this 64 | * object to a String, at one or more positions that are 65 | * greater than or equal to position; otherwise, returns false. 66 | * @param searchString search string 67 | * @param position If position is undefined, 0 is assumed, so as to search all of the String. 68 | */ 69 | includes(searchString: string, position?: number): boolean; 70 | 71 | /** 72 | * Returns true if the sequence of elements of searchString converted to a String is the 73 | * same as the corresponding elements of this object (converted to a String) starting at 74 | * endPosition – length(this). Otherwise returns false. 75 | */ 76 | endsWith(searchString: string, endPosition?: number): boolean; 77 | 78 | /** 79 | * Returns a String value that is made from count copies appended together. If count is 0, 80 | * T is the empty String is returned. 81 | * @param count number of copies to append 82 | */ 83 | repeat(count: number): string; 84 | 85 | /** 86 | * Returns true if the sequence of elements of searchString converted to a String is the 87 | * same as the corresponding elements of this object (converted to a String) starting at 88 | * position. Otherwise returns false. 89 | */ 90 | startsWith(searchString: string, position?: number): boolean; 91 | 92 | /** 93 | * Returns an HTML anchor element and sets the name attribute to the text value 94 | * @param name 95 | */ 96 | anchor(name: string): string; 97 | 98 | /** Returns a HTML element */ 99 | big(): string; 100 | 101 | /** Returns a HTML element */ 102 | blink(): string; 103 | 104 | /** Returns a HTML element */ 105 | bold(): string; 106 | 107 | /** Returns a HTML element */ 108 | fixed(): string 109 | 110 | /** Returns a HTML element and sets the color attribute value */ 111 | fontcolor(color: string): string 112 | 113 | /** Returns a HTML element and sets the size attribute value */ 114 | fontsize(size: number): string; 115 | 116 | /** Returns a HTML element and sets the size attribute value */ 117 | fontsize(size: string): string; 118 | 119 | /** Returns an HTML element */ 120 | italics(): string; 121 | 122 | /** Returns an HTML element and sets the href attribute value */ 123 | link(url: string): string; 124 | 125 | /** Returns a HTML element */ 126 | small(): string; 127 | 128 | /** Returns a HTML element */ 129 | strike(): string; 130 | 131 | /** Returns a HTML element */ 132 | sub(): string; 133 | 134 | /** Returns a HTML element */ 135 | sup(): string; 136 | 137 | /** 138 | * Shim for an ES6 iterable. Not intended for direct use by user code. 139 | */ 140 | "_es6-shim iterator_"(): IterableIteratorShim; 141 | } 142 | 143 | interface ArrayConstructor { 144 | /** 145 | * Creates an array from an array-like object. 146 | * @param arrayLike An array-like object to convert to an array. 147 | * @param mapfn A mapping function to call on every element of the array. 148 | * @param thisArg Value of 'this' used to invoke the mapfn. 149 | */ 150 | from(arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): Array; 151 | 152 | /** 153 | * Creates an array from an iterable object. 154 | * @param iterable An iterable object to convert to an array. 155 | * @param mapfn A mapping function to call on every element of the array. 156 | * @param thisArg Value of 'this' used to invoke the mapfn. 157 | */ 158 | from(iterable: IterableShim, mapfn: (v: T, k: number) => U, thisArg?: any): Array; 159 | 160 | /** 161 | * Creates an array from an array-like object. 162 | * @param arrayLike An array-like object to convert to an array. 163 | */ 164 | from(arrayLike: ArrayLike): Array; 165 | 166 | /** 167 | * Creates an array from an iterable object. 168 | * @param iterable An iterable object to convert to an array. 169 | */ 170 | from(iterable: IterableShim): Array; 171 | 172 | /** 173 | * Returns a new array from a set of elements. 174 | * @param items A set of elements to include in the new array object. 175 | */ 176 | of(...items: T[]): Array; 177 | } 178 | 179 | interface Array { 180 | /** 181 | * Returns the value of the first element in the array where predicate is true, and undefined 182 | * otherwise. 183 | * @param predicate find calls predicate once for each element of the array, in ascending 184 | * order, until it finds one where predicate returns true. If such an element is found, find 185 | * immediately returns that element value. Otherwise, find returns undefined. 186 | * @param thisArg If provided, it will be used as the this value for each invocation of 187 | * predicate. If it is not provided, undefined is used instead. 188 | */ 189 | find(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): T; 190 | 191 | /** 192 | * Returns the index of the first element in the array where predicate is true, and undefined 193 | * otherwise. 194 | * @param predicate find calls predicate once for each element of the array, in ascending 195 | * order, until it finds one where predicate returns true. If such an element is found, find 196 | * immediately returns that element value. Otherwise, find returns undefined. 197 | * @param thisArg If provided, it will be used as the this value for each invocation of 198 | * predicate. If it is not provided, undefined is used instead. 199 | */ 200 | findIndex(predicate: (value: T) => boolean, thisArg?: any): number; 201 | 202 | /** 203 | * Returns the this object after filling the section identified by start and end with value 204 | * @param value value to fill array section with 205 | * @param start index to start filling the array at. If start is negative, it is treated as 206 | * length+start where length is the length of the array. 207 | * @param end index to stop filling the array at. If end is negative, it is treated as 208 | * length+end. 209 | */ 210 | fill(value: T, start?: number, end?: number): T[]; 211 | 212 | /** 213 | * Returns the this object after copying a section of the array identified by start and end 214 | * to the same array starting at position target 215 | * @param target If target is negative, it is treated as length+target where length is the 216 | * length of the array. 217 | * @param start If start is negative, it is treated as length+start. If end is negative, it 218 | * is treated as length+end. 219 | * @param end If not specified, length of the this object is used as its default value. 220 | */ 221 | copyWithin(target: number, start: number, end?: number): T[]; 222 | 223 | /** 224 | * Returns an array of key, value pairs for every entry in the array 225 | */ 226 | entries(): IterableIteratorShim<[number, T]>; 227 | 228 | /** 229 | * Returns an list of keys in the array 230 | */ 231 | keys(): IterableIteratorShim; 232 | 233 | /** 234 | * Returns an list of values in the array 235 | */ 236 | values(): IterableIteratorShim; 237 | 238 | /** 239 | * Shim for an ES6 iterable. Not intended for direct use by user code. 240 | */ 241 | "_es6-shim iterator_"(): IterableIteratorShim; 242 | } 243 | 244 | interface NumberConstructor { 245 | /** 246 | * The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1 247 | * that is representable as a Number value, which is approximately: 248 | * 2.2204460492503130808472633361816 x 10‍−‍16. 249 | */ 250 | EPSILON: number; 251 | 252 | /** 253 | * Returns true if passed value is finite. 254 | * Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a 255 | * number. Only finite values of the type number, result in true. 256 | * @param number A numeric value. 257 | */ 258 | isFinite(number: number): boolean; 259 | 260 | /** 261 | * Returns true if the value passed is an integer, false otherwise. 262 | * @param number A numeric value. 263 | */ 264 | isInteger(number: number): boolean; 265 | 266 | /** 267 | * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a 268 | * number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter 269 | * to a number. Only values of the type number, that are also NaN, result in true. 270 | * @param number A numeric value. 271 | */ 272 | isNaN(number: number): boolean; 273 | 274 | /** 275 | * Returns true if the value passed is a safe integer. 276 | * @param number A numeric value. 277 | */ 278 | isSafeInteger(number: number): boolean; 279 | 280 | /** 281 | * The value of the largest integer n such that n and n + 1 are both exactly representable as 282 | * a Number value. 283 | * The value of Number.MIN_SAFE_INTEGER is 9007199254740991 2^53 − 1. 284 | */ 285 | MAX_SAFE_INTEGER: number; 286 | 287 | /** 288 | * The value of the smallest integer n such that n and n − 1 are both exactly representable as 289 | * a Number value. 290 | * The value of Number.MIN_SAFE_INTEGER is −9007199254740991 (−(2^53 − 1)). 291 | */ 292 | MIN_SAFE_INTEGER: number; 293 | 294 | /** 295 | * Converts a string to a floating-point number. 296 | * @param string A string that contains a floating-point number. 297 | */ 298 | parseFloat(string: string): number; 299 | 300 | /** 301 | * Converts A string to an integer. 302 | * @param s A string to convert into a number. 303 | * @param radix A value between 2 and 36 that specifies the base of the number in numString. 304 | * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. 305 | * All other strings are considered decimal. 306 | */ 307 | parseInt(string: string, radix?: number): number; 308 | } 309 | 310 | interface ObjectConstructor { 311 | /** 312 | * Copy the values of all of the enumerable own properties from one or more source objects to a 313 | * target object. Returns the target object. 314 | * @param target The target object to copy to. 315 | * @param sources One or more source objects to copy properties from. 316 | */ 317 | assign(target: any, ...sources: any[]): any; 318 | 319 | /** 320 | * Returns true if the values are the same value, false otherwise. 321 | * @param value1 The first value. 322 | * @param value2 The second value. 323 | */ 324 | is(value1: any, value2: any): boolean; 325 | 326 | /** 327 | * Sets the prototype of a specified object o to object proto or null. Returns the object o. 328 | * @param o The object to change its prototype. 329 | * @param proto The value of the new prototype or null. 330 | * @remarks Requires `__proto__` support. 331 | */ 332 | setPrototypeOf(o: any, proto: any): any; 333 | } 334 | 335 | interface RegExp { 336 | /** 337 | * Returns a string indicating the flags of the regular expression in question. This field is read-only. 338 | * The characters in this string are sequenced and concatenated in the following order: 339 | * 340 | * - "g" for global 341 | * - "i" for ignoreCase 342 | * - "m" for multiline 343 | * - "u" for unicode 344 | * - "y" for sticky 345 | * 346 | * If no flags are set, the value is the empty string. 347 | */ 348 | flags: string; 349 | } 350 | 351 | interface Math { 352 | /** 353 | * Returns the number of leading zero bits in the 32-bit binary representation of a number. 354 | * @param x A numeric expression. 355 | */ 356 | clz32(x: number): number; 357 | 358 | /** 359 | * Returns the result of 32-bit multiplication of two numbers. 360 | * @param x First number 361 | * @param y Second number 362 | */ 363 | imul(x: number, y: number): number; 364 | 365 | /** 366 | * Returns the sign of the x, indicating whether x is positive, negative or zero. 367 | * @param x The numeric expression to test 368 | */ 369 | sign(x: number): number; 370 | 371 | /** 372 | * Returns the base 10 logarithm of a number. 373 | * @param x A numeric expression. 374 | */ 375 | log10(x: number): number; 376 | 377 | /** 378 | * Returns the base 2 logarithm of a number. 379 | * @param x A numeric expression. 380 | */ 381 | log2(x: number): number; 382 | 383 | /** 384 | * Returns the natural logarithm of 1 + x. 385 | * @param x A numeric expression. 386 | */ 387 | log1p(x: number): number; 388 | 389 | /** 390 | * Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of 391 | * the natural logarithms). 392 | * @param x A numeric expression. 393 | */ 394 | expm1(x: number): number; 395 | 396 | /** 397 | * Returns the hyperbolic cosine of a number. 398 | * @param x A numeric expression that contains an angle measured in radians. 399 | */ 400 | cosh(x: number): number; 401 | 402 | /** 403 | * Returns the hyperbolic sine of a number. 404 | * @param x A numeric expression that contains an angle measured in radians. 405 | */ 406 | sinh(x: number): number; 407 | 408 | /** 409 | * Returns the hyperbolic tangent of a number. 410 | * @param x A numeric expression that contains an angle measured in radians. 411 | */ 412 | tanh(x: number): number; 413 | 414 | /** 415 | * Returns the inverse hyperbolic cosine of a number. 416 | * @param x A numeric expression that contains an angle measured in radians. 417 | */ 418 | acosh(x: number): number; 419 | 420 | /** 421 | * Returns the inverse hyperbolic sine of a number. 422 | * @param x A numeric expression that contains an angle measured in radians. 423 | */ 424 | asinh(x: number): number; 425 | 426 | /** 427 | * Returns the inverse hyperbolic tangent of a number. 428 | * @param x A numeric expression that contains an angle measured in radians. 429 | */ 430 | atanh(x: number): number; 431 | 432 | /** 433 | * Returns the square root of the sum of squares of its arguments. 434 | * @param values Values to compute the square root for. 435 | * If no arguments are passed, the result is +0. 436 | * If there is only one argument, the result is the absolute value. 437 | * If any argument is +Infinity or -Infinity, the result is +Infinity. 438 | * If any argument is NaN, the result is NaN. 439 | * If all arguments are either +0 or −0, the result is +0. 440 | */ 441 | hypot(...values: number[]): number; 442 | 443 | /** 444 | * Returns the integral part of the a numeric expression, x, removing any fractional digits. 445 | * If x is already an integer, the result is x. 446 | * @param x A numeric expression. 447 | */ 448 | trunc(x: number): number; 449 | 450 | /** 451 | * Returns the nearest single precision float representation of a number. 452 | * @param x A numeric expression. 453 | */ 454 | fround(x: number): number; 455 | 456 | /** 457 | * Returns an implementation-dependent approximation to the cube root of number. 458 | * @param x A numeric expression. 459 | */ 460 | cbrt(x: number): number; 461 | } 462 | 463 | interface PromiseLike { 464 | /** 465 | * Attaches callbacks for the resolution and/or rejection of the Promise. 466 | * @param onfulfilled The callback to execute when the Promise is resolved. 467 | * @param onrejected The callback to execute when the Promise is rejected. 468 | * @returns A Promise for the completion of which ever callback is executed. 469 | */ 470 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): PromiseLike; 471 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): PromiseLike; 472 | } 473 | 474 | /** 475 | * Represents the completion of an asynchronous operation 476 | */ 477 | interface Promise { 478 | /** 479 | * Attaches callbacks for the resolution and/or rejection of the Promise. 480 | * @param onfulfilled The callback to execute when the Promise is resolved. 481 | * @param onrejected The callback to execute when the Promise is rejected. 482 | * @returns A Promise for the completion of which ever callback is executed. 483 | */ 484 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): Promise; 485 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): Promise; 486 | 487 | /** 488 | * Attaches a callback for only the rejection of the Promise. 489 | * @param onrejected The callback to execute when the Promise is rejected. 490 | * @returns A Promise for the completion of the callback. 491 | */ 492 | catch(onrejected?: (reason: any) => T | PromiseLike): Promise; 493 | catch(onrejected?: (reason: any) => void): Promise; 494 | } 495 | 496 | interface PromiseConstructor { 497 | /** 498 | * A reference to the prototype. 499 | */ 500 | prototype: Promise; 501 | 502 | /** 503 | * Creates a new Promise. 504 | * @param executor A callback used to initialize the promise. This callback is passed two arguments: 505 | * a resolve callback used resolve the promise with a value or the result of another promise, 506 | * and a reject callback used to reject the promise with a provided reason or error. 507 | */ 508 | new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; 509 | 510 | /** 511 | * Creates a Promise that is resolved with an array of results when all of the provided Promises 512 | * resolve, or rejected when any Promise is rejected. 513 | * @param values An array of Promises. 514 | * @returns A new Promise. 515 | */ 516 | all(values: IterableShim>): Promise; 517 | 518 | /** 519 | * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 520 | * or rejected. 521 | * @param values An array of Promises. 522 | * @returns A new Promise. 523 | */ 524 | race(values: IterableShim>): Promise; 525 | 526 | /** 527 | * Creates a new rejected promise for the provided reason. 528 | * @param reason The reason the promise was rejected. 529 | * @returns A new rejected Promise. 530 | */ 531 | reject(reason: any): Promise; 532 | 533 | /** 534 | * Creates a new rejected promise for the provided reason. 535 | * @param reason The reason the promise was rejected. 536 | * @returns A new rejected Promise. 537 | */ 538 | reject(reason: any): Promise; 539 | 540 | /** 541 | * Creates a new resolved promise for the provided value. 542 | * @param value A promise. 543 | * @returns A promise whose internal state matches the provided promise. 544 | */ 545 | resolve(value: T | PromiseLike): Promise; 546 | 547 | /** 548 | * Creates a new resolved promise . 549 | * @returns A resolved promise. 550 | */ 551 | resolve(): Promise; 552 | } 553 | 554 | declare var Promise: PromiseConstructor; 555 | 556 | interface Map { 557 | clear(): void; 558 | delete(key: K): boolean; 559 | forEach(callbackfn: (value: V, index: K, map: Map) => void, thisArg?: any): void; 560 | get(key: K): V; 561 | has(key: K): boolean; 562 | set(key: K, value?: V): Map; 563 | size: number; 564 | entries(): IterableIteratorShim<[K, V]>; 565 | keys(): IterableIteratorShim; 566 | values(): IterableIteratorShim; 567 | } 568 | 569 | interface MapConstructor { 570 | new (): Map; 571 | new (iterable: IterableShim<[K, V]>): Map; 572 | prototype: Map; 573 | } 574 | 575 | declare var Map: MapConstructor; 576 | 577 | interface Set { 578 | add(value: T): Set; 579 | clear(): void; 580 | delete(value: T): boolean; 581 | forEach(callbackfn: (value: T, index: T, set: Set) => void, thisArg?: any): void; 582 | has(value: T): boolean; 583 | size: number; 584 | entries(): IterableIteratorShim<[T, T]>; 585 | keys(): IterableIteratorShim; 586 | values(): IterableIteratorShim; 587 | } 588 | 589 | interface SetConstructor { 590 | new (): Set; 591 | new (iterable: IterableShim): Set; 592 | prototype: Set; 593 | } 594 | 595 | declare var Set: SetConstructor; 596 | 597 | interface WeakMap { 598 | delete(key: K): boolean; 599 | get(key: K): V; 600 | has(key: K): boolean; 601 | set(key: K, value?: V): WeakMap; 602 | } 603 | 604 | interface WeakMapConstructor { 605 | new (): WeakMap; 606 | new (iterable: IterableShim<[K, V]>): WeakMap; 607 | prototype: WeakMap; 608 | } 609 | 610 | declare var WeakMap: WeakMapConstructor; 611 | 612 | interface WeakSet { 613 | add(value: T): WeakSet; 614 | delete(value: T): boolean; 615 | has(value: T): boolean; 616 | } 617 | 618 | interface WeakSetConstructor { 619 | new (): WeakSet; 620 | new (iterable: IterableShim): WeakSet; 621 | prototype: WeakSet; 622 | } 623 | 624 | declare var WeakSet: WeakSetConstructor; 625 | 626 | declare namespace Reflect { 627 | function apply(target: Function, thisArgument: any, argumentsList: ArrayLike): any; 628 | function construct(target: Function, argumentsList: ArrayLike): any; 629 | function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean; 630 | function deleteProperty(target: any, propertyKey: PropertyKey): boolean; 631 | function enumerate(target: any): IterableIteratorShim; 632 | function get(target: any, propertyKey: PropertyKey, receiver?: any): any; 633 | function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor; 634 | function getPrototypeOf(target: any): any; 635 | function has(target: any, propertyKey: PropertyKey): boolean; 636 | function isExtensible(target: any): boolean; 637 | function ownKeys(target: any): Array; 638 | function preventExtensions(target: any): boolean; 639 | function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean; 640 | function setPrototypeOf(target: any, proto: any): boolean; 641 | } 642 | 643 | declare module "es6-shim" { 644 | var String: StringConstructor; 645 | var Array: ArrayConstructor; 646 | var Number: NumberConstructor; 647 | var Math: Math; 648 | var Object: ObjectConstructor; 649 | var Map: MapConstructor; 650 | var Set: SetConstructor; 651 | var WeakMap: WeakMapConstructor; 652 | var WeakSet: WeakSetConstructor; 653 | var Promise: PromiseConstructor; 654 | namespace Reflect { 655 | function apply(target: Function, thisArgument: any, argumentsList: ArrayLike): any; 656 | function construct(target: Function, argumentsList: ArrayLike): any; 657 | function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean; 658 | function deleteProperty(target: any, propertyKey: PropertyKey): boolean; 659 | function enumerate(target: any): Iterator; 660 | function get(target: any, propertyKey: PropertyKey, receiver?: any): any; 661 | function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor; 662 | function getPrototypeOf(target: any): any; 663 | function has(target: any, propertyKey: PropertyKey): boolean; 664 | function isExtensible(target: any): boolean; 665 | function ownKeys(target: any): Array; 666 | function preventExtensions(target: any): boolean; 667 | function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean; 668 | function setPrototypeOf(target: any, proto: any): boolean; 669 | } 670 | } -------------------------------------------------------------------------------- /typings/browser/ambient/webrtc/mediastream/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/webrtc/MediaStream.d.ts 3 | // Type definitions for WebRTC 4 | // Project: http://dev.w3.org/2011/webrtc/ 5 | // Definitions by: Ken Smith 6 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 7 | 8 | // Taken from http://dev.w3.org/2011/webrtc/editor/getusermedia.html 9 | // version: W3C Editor's Draft 29 June 2015 10 | 11 | interface ConstrainBooleanParameters { 12 | exact?: boolean; 13 | ideal?: boolean; 14 | } 15 | 16 | interface NumberRange { 17 | max?: number; 18 | min?: number; 19 | } 20 | 21 | interface ConstrainNumberRange extends NumberRange { 22 | exact?: number; 23 | ideal?: number; 24 | } 25 | 26 | interface ConstrainStringParameters { 27 | exact?: string | string[]; 28 | ideal?: string | string[]; 29 | } 30 | 31 | interface MediaStreamConstraints { 32 | video?: boolean | MediaTrackConstraints; 33 | audio?: boolean | MediaTrackConstraints; 34 | } 35 | 36 | declare namespace W3C { 37 | type LongRange = NumberRange; 38 | type DoubleRange = NumberRange; 39 | type ConstrainBoolean = boolean | ConstrainBooleanParameters; 40 | type ConstrainNumber = number | ConstrainNumberRange; 41 | type ConstrainLong = ConstrainNumber; 42 | type ConstrainDouble = ConstrainNumber; 43 | type ConstrainString = string | string[] | ConstrainStringParameters; 44 | } 45 | 46 | interface MediaTrackConstraints extends MediaTrackConstraintSet { 47 | advanced?: MediaTrackConstraintSet[]; 48 | } 49 | 50 | interface MediaTrackConstraintSet { 51 | width?: W3C.ConstrainLong; 52 | height?: W3C.ConstrainLong; 53 | aspectRatio?: W3C.ConstrainDouble; 54 | frameRate?: W3C.ConstrainDouble; 55 | facingMode?: W3C.ConstrainString; 56 | volume?: W3C.ConstrainDouble; 57 | sampleRate?: W3C.ConstrainLong; 58 | sampleSize?: W3C.ConstrainLong; 59 | echoCancellation?: W3C.ConstrainBoolean; 60 | latency?: W3C.ConstrainDouble; 61 | deviceId?: W3C.ConstrainString; 62 | groupId?: W3C.ConstrainString; 63 | } 64 | 65 | interface MediaTrackSupportedConstraints { 66 | width?: boolean; 67 | height?: boolean; 68 | aspectRatio?: boolean; 69 | frameRate?: boolean; 70 | facingMode?: boolean; 71 | volume?: boolean; 72 | sampleRate?: boolean; 73 | sampleSize?: boolean; 74 | echoCancellation?: boolean; 75 | latency?: boolean; 76 | deviceId?: boolean; 77 | groupId?: boolean; 78 | } 79 | 80 | interface MediaStream extends EventTarget { 81 | id: string; 82 | active: boolean; 83 | 84 | onactive: EventListener; 85 | oninactive: EventListener; 86 | onaddtrack: (event: MediaStreamTrackEvent) => any; 87 | onremovetrack: (event: MediaStreamTrackEvent) => any; 88 | 89 | clone(): MediaStream; 90 | stop(): void; 91 | 92 | getAudioTracks(): MediaStreamTrack[]; 93 | getVideoTracks(): MediaStreamTrack[]; 94 | getTracks(): MediaStreamTrack[]; 95 | 96 | getTrackById(trackId: string): MediaStreamTrack; 97 | 98 | addTrack(track: MediaStreamTrack): void; 99 | removeTrack(track: MediaStreamTrack): void; 100 | } 101 | 102 | interface MediaStreamTrackEvent extends Event { 103 | track: MediaStreamTrack; 104 | } 105 | 106 | declare enum MediaStreamTrackState { 107 | "live", 108 | "ended" 109 | } 110 | 111 | interface MediaStreamTrack extends EventTarget { 112 | id: string; 113 | kind: string; 114 | label: string; 115 | enabled: boolean; 116 | muted: boolean; 117 | remote: boolean; 118 | readyState: MediaStreamTrackState; 119 | 120 | onmute: EventListener; 121 | onunmute: EventListener; 122 | onended: EventListener; 123 | onoverconstrained: EventListener; 124 | 125 | clone(): MediaStreamTrack; 126 | 127 | stop(): void; 128 | 129 | getCapabilities(): MediaTrackCapabilities; 130 | getConstraints(): MediaTrackConstraints; 131 | getSettings(): MediaTrackSettings; 132 | applyConstraints(constraints: MediaTrackConstraints): Promise; 133 | } 134 | 135 | interface MediaTrackCapabilities { 136 | width: number | W3C.LongRange; 137 | height: number | W3C.LongRange; 138 | aspectRatio: number | W3C.DoubleRange; 139 | frameRate: number | W3C.DoubleRange; 140 | facingMode: string; 141 | volume: number | W3C.DoubleRange; 142 | sampleRate: number | W3C.LongRange; 143 | sampleSize: number | W3C.LongRange; 144 | echoCancellation: boolean[]; 145 | latency: number | W3C.DoubleRange; 146 | deviceId: string; 147 | groupId: string; 148 | } 149 | 150 | interface MediaTrackSettings { 151 | width: number; 152 | height: number; 153 | aspectRatio: number; 154 | frameRate: number; 155 | facingMode: string; 156 | volume: number; 157 | sampleRate: number; 158 | sampleSize: number; 159 | echoCancellation: boolean; 160 | latency: number; 161 | deviceId: string; 162 | groupId: string; 163 | } 164 | 165 | interface MediaStreamError { 166 | name: string; 167 | message: string; 168 | constraintName: string; 169 | } 170 | 171 | interface NavigatorGetUserMedia { 172 | (constraints: MediaStreamConstraints, 173 | successCallback: (stream: MediaStream) => void, 174 | errorCallback: (error: MediaStreamError) => void): void; 175 | } 176 | 177 | // to use with adapter.js, see: https://github.com/webrtc/adapter 178 | declare var getUserMedia: NavigatorGetUserMedia; 179 | 180 | interface Navigator { 181 | getUserMedia: NavigatorGetUserMedia; 182 | 183 | webkitGetUserMedia: NavigatorGetUserMedia; 184 | 185 | mozGetUserMedia: NavigatorGetUserMedia; 186 | 187 | msGetUserMedia: NavigatorGetUserMedia; 188 | 189 | mediaDevices: MediaDevices; 190 | } 191 | 192 | interface MediaDevices { 193 | getSupportedConstraints(): MediaTrackSupportedConstraints; 194 | 195 | getUserMedia(constraints: MediaStreamConstraints): Promise; 196 | enumerateDevices(): Promise; 197 | } 198 | 199 | interface MediaDeviceInfo { 200 | label: string; 201 | deviceId: string; 202 | kind: string; 203 | groupId: string; 204 | } -------------------------------------------------------------------------------- /typings/browser/definitions/annyang/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/theluk/typed-annyang/bcd191374316617db56f4737874e520a93ab6bf9/index.d.ts 3 | declare module '~annyang/index' { 4 | /** 5 | * Options for function `start` 6 | * 7 | * @export 8 | * @interface StartOptions 9 | */ 10 | export interface StartOptions { 11 | /** 12 | * Should annyang restart itself if it is closed indirectly, because of silence or window conflicts? 13 | * 14 | * @type {boolean} 15 | */ 16 | autoRestart? : boolean; 17 | /** 18 | * Allow forcing continuous mode on or off. Annyang is pretty smart about this, so only set this if you know what you're doing. 19 | * 20 | * @type {boolean} 21 | */ 22 | continuous? : boolean; 23 | } 24 | /** 25 | * A command option that supports custom regular expressions 26 | * 27 | * @export 28 | * @interface CommandOptionRegex 29 | */ 30 | export interface CommandOptionRegex { 31 | /** 32 | * @type {RegExp} 33 | */ 34 | regexp: RegExp; 35 | /** 36 | * @type {() => any} 37 | */ 38 | callback: () => void; 39 | } 40 | /** 41 | * Commands that annyang should listen to 42 | * 43 | * #### Examples: 44 | * ````javascript 45 | * {'hello :name': helloFunction, 'howdy': helloFunction}; 46 | * {'hi': helloFunction}; 47 | * ```` 48 | * @export 49 | * @interface CommandOption 50 | */ 51 | export interface CommandOption { 52 | [command:string]: CommandOptionRegex | (() => void); 53 | } 54 | /** 55 | * Supported Events that will be triggered to listeners, you attach using `annyang.addCallback()` 56 | * 57 | * `start` - Fired as soon as the browser's Speech Recognition engine starts listening 58 | * `error` - Fired when the browser's Speech Recogntion engine returns an error, this generic error callback will be followed by more accurate error callbacks (both will fire if both are defined) 59 | * `errorNetwork` - Fired when Speech Recognition fails because of a network error 60 | * `errorPermissionBlocked` - Fired when the browser blocks the permission request to use Speech Recognition. 61 | * `errorPermissionDenied` - Fired when the user blocks the permission request to use Speech Recognition. 62 | * `end` - Fired when the browser's Speech Recognition engine stops 63 | * `result` - Fired as soon as some speech was identified. This generic callback will be followed by either the `resultMatch` or `resultNoMatch` callbacks. 64 | * Callback functions registered to this event will include an array of possible phrases the user said as the first argument 65 | * `resultMatch` - Fired when annyang was able to match between what the user said and a registered command 66 | * Callback functions registered to this event will include three arguments in the following order: 67 | * * The phrase the user said that matched a command 68 | * * The command that was matched 69 | * * An array of possible alternative phrases the user might've said 70 | * `resultNoMatch` - Fired when what the user said didn't match any of the registered commands. 71 | * Callback functions registered to this event will include an array of possible phrases the user might've said as the first argument 72 | */ 73 | export type Events = "resultstart" | 74 | "error" | 75 | "end" | 76 | "result" | 77 | "resultMatch" | 78 | "resultNoMatch" | 79 | "errorNetwork" | 80 | "errorPermissionBlocked" | 81 | "errorPermissionDenied"; 82 | /** 83 | * Start listening. 84 | * It's a good idea to call this after adding some commands first, but not mandatory. 85 | * 86 | * @export 87 | * @param {StartOptions} options 88 | */ 89 | export function start(options : StartOptions) : void 90 | /** 91 | * Stop listening, and turn off mic. 92 | * 93 | * @export 94 | */ 95 | export function abort() : void 96 | /** 97 | * Pause listening. annyang will stop responding to commands (until the resume or start methods are called), without turning off the browser's SpeechRecognition engine or the mic. 98 | * 99 | * @export 100 | */ 101 | export function pause() : void 102 | /** 103 | * Resumes listening and restores command callback execution when a result matches. 104 | * If SpeechRecognition was aborted (stopped), start it. 105 | * 106 | * @export 107 | */ 108 | export function resume() : void 109 | /** 110 | * Turn on output of debug messages to the console. Ugly, but super-handy! 111 | * 112 | * @export 113 | * @param {boolean} [newState=true] Turn on/off debug messages 114 | */ 115 | export function debug(newState? : boolean) : void 116 | /** 117 | * Set the language the user will speak in. If this method is not called, defaults to 'en-US'. 118 | * 119 | * @export 120 | * @param {string} lang 121 | * @see [Languages](https://github.com/TalAter/annyang/blob/master/docs/FAQ.md#what-languages-are-supported) 122 | */ 123 | export function setLanguage(lang : string) : void 124 | /** 125 | * Add commands that annyang will respond to. Similar in syntax to init(), but doesn't remove existing commands. 126 | * 127 | * #### Examples: 128 | * ````javascript 129 | * var commands = {'hello :name': helloFunction, 'howdy': helloFunction}; 130 | * var commands2 = {'hi': helloFunction}; 131 | * 132 | * annyang.addCommands(commands); 133 | * annyang.addCommands(commands2); 134 | * // annyang will now listen to all three commands 135 | * ```` 136 | * 137 | * @export 138 | * @param {CommandOption} commands 139 | */ 140 | export function addCommands(commands : CommandOption) : void 141 | /** 142 | * Remove all existing commands. 143 | * 144 | * #### Examples: 145 | * ````javascript 146 | * var commands : annyang.CommandOption = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction}; 147 | * 148 | * // Remove all existing commands 149 | * annyang.removeCommands(); 150 | * ```` 151 | * @export 152 | */ 153 | export function removeCommands() : void 154 | /** 155 | * Removes a command 156 | * #### Examples: 157 | * ````javascript 158 | * // Don't respond to hello 159 | * annyang.removeCommands('hello'); 160 | * ```` 161 | * @export 162 | * @param {string} command 163 | */ 164 | export function removeCommands(command : string) : void 165 | /** 166 | * Removes a list of commands 167 | * #### Examples: 168 | * ````javascript 169 | * var commands : annyang.CommandOption = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction}; 170 | * // Add some commands 171 | * annyang.addCommands(commands); 172 | * // Don't respond to howdy or hi 173 | * annyang.removeCommands(['howdy', 'hi']); 174 | * ```` 175 | * 176 | * @export 177 | * @param {string[]} command 178 | */ 179 | export function removeCommands(command : string[]) : void 180 | /** 181 | * Add a callback function to be called, when a Event occures 182 | * 183 | * @export 184 | * @param {Events} event 185 | * @param {Function} callback 186 | * @param {*} [context] 187 | */ 188 | export function addCallback(event : Events, callback : () => void, context? : any) : void 189 | /** 190 | * Add a callback function to be called, when a Event occures 191 | * 192 | * @export 193 | * @param {Events} event 194 | * @param {(results : string[]) => void} callback 195 | * @param {*} [context] 196 | */ 197 | export function addCallback(event : Events, callback : (results : string[]) => void, context? : any) : void 198 | /** 199 | * @export 200 | * @param {Events} event 201 | * @param {(userSaid : string, commandText : string, results : string[]) => void} callback 202 | * @param {*} [context] 203 | */ 204 | export function addCallback(event : Events, callback : (userSaid : string, commandText : string, results : string[]) => void, context? : any) : void 205 | /** 206 | * @export 207 | * @param {Events} [event] 208 | * @param {Function} [callback] 209 | */ 210 | export function removeCallback(event? : Events, callback? : Function) : void 211 | /** 212 | * Returns true if speech recognition is currently on. 213 | * Returns false if speech recognition is off or annyang is paused. 214 | * 215 | * @export 216 | * @returns {boolean} 217 | */ 218 | export function isListening() : boolean 219 | /** 220 | * Returns the instance of the browser's SpeechRecognition object used by annyang. 221 | * Useful in case you want direct access to the browser's Speech Recognition engine. 222 | * 223 | * @export 224 | * @returns {*} 225 | */ 226 | export function getSpeechRecognizer() : any 227 | /** 228 | * Simulate speech being recognized. This will trigger the same events and behavior as when the Speech Recognition 229 | * detects speech. 230 | * 231 | * Can accept either a string containing a single sentence, or an array containing multiple sentences to be checked 232 | * in order until one of them matches a command (similar to the way Speech Recognition Alternatives are parsed) 233 | * 234 | * #### Examples: 235 | * ````javascript 236 | * annyang.trigger('Time for some thrilling heroics'); 237 | * annyang.trigger( 238 | * ['Time for some thrilling heroics', 'Time for some thrilling aerobics'] 239 | * ); 240 | * ```` 241 | * 242 | * @export 243 | * @param {string} command 244 | */ 245 | export function trigger(command : string) : void 246 | /** 247 | * @export 248 | * @param {string[]} command 249 | */ 250 | export function trigger(command : string[]) : void 251 | } 252 | declare module 'annyang/index' { 253 | export * from '~annyang/index'; 254 | } 255 | declare module 'annyang' { 256 | export * from '~annyang/index'; 257 | } 258 | -------------------------------------------------------------------------------- /typings/globals/es6-shim/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/9807d9b701f58be068cb07833d2b24235351d052/es6-shim/es6-shim.d.ts 3 | declare type PropertyKey = string | number | symbol; 4 | 5 | interface IteratorResult { 6 | done: boolean; 7 | value?: T; 8 | } 9 | 10 | interface IterableShim { 11 | /** 12 | * Shim for an ES6 iterable. Not intended for direct use by user code. 13 | */ 14 | "_es6-shim iterator_"(): Iterator; 15 | } 16 | 17 | interface Iterator { 18 | next(value?: any): IteratorResult; 19 | return?(value?: any): IteratorResult; 20 | throw?(e?: any): IteratorResult; 21 | } 22 | 23 | interface IterableIteratorShim extends IterableShim, Iterator { 24 | /** 25 | * Shim for an ES6 iterable iterator. Not intended for direct use by user code. 26 | */ 27 | "_es6-shim iterator_"(): IterableIteratorShim; 28 | } 29 | 30 | interface StringConstructor { 31 | /** 32 | * Return the String value whose elements are, in order, the elements in the List elements. 33 | * If length is 0, the empty string is returned. 34 | */ 35 | fromCodePoint(...codePoints: number[]): string; 36 | 37 | /** 38 | * String.raw is intended for use as a tag function of a Tagged Template String. When called 39 | * as such the first argument will be a well formed template call site object and the rest 40 | * parameter will contain the substitution values. 41 | * @param template A well-formed template string call site representation. 42 | * @param substitutions A set of substitution values. 43 | */ 44 | raw(template: TemplateStringsArray, ...substitutions: any[]): string; 45 | } 46 | 47 | interface String { 48 | /** 49 | * Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point 50 | * value of the UTF-16 encoded code point starting at the string element at position pos in 51 | * the String resulting from converting this object to a String. 52 | * If there is no element at that position, the result is undefined. 53 | * If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos. 54 | */ 55 | codePointAt(pos: number): number; 56 | 57 | /** 58 | * Returns true if searchString appears as a substring of the result of converting this 59 | * object to a String, at one or more positions that are 60 | * greater than or equal to position; otherwise, returns false. 61 | * @param searchString search string 62 | * @param position If position is undefined, 0 is assumed, so as to search all of the String. 63 | */ 64 | includes(searchString: string, position?: number): boolean; 65 | 66 | /** 67 | * Returns true if the sequence of elements of searchString converted to a String is the 68 | * same as the corresponding elements of this object (converted to a String) starting at 69 | * endPosition – length(this). Otherwise returns false. 70 | */ 71 | endsWith(searchString: string, endPosition?: number): boolean; 72 | 73 | /** 74 | * Returns a String value that is made from count copies appended together. If count is 0, 75 | * T is the empty String is returned. 76 | * @param count number of copies to append 77 | */ 78 | repeat(count: number): string; 79 | 80 | /** 81 | * Returns true if the sequence of elements of searchString converted to a String is the 82 | * same as the corresponding elements of this object (converted to a String) starting at 83 | * position. Otherwise returns false. 84 | */ 85 | startsWith(searchString: string, position?: number): boolean; 86 | 87 | /** 88 | * Returns an HTML anchor element and sets the name attribute to the text value 89 | * @param name 90 | */ 91 | anchor(name: string): string; 92 | 93 | /** Returns a HTML element */ 94 | big(): string; 95 | 96 | /** Returns a HTML element */ 97 | blink(): string; 98 | 99 | /** Returns a HTML element */ 100 | bold(): string; 101 | 102 | /** Returns a HTML element */ 103 | fixed(): string 104 | 105 | /** Returns a HTML element and sets the color attribute value */ 106 | fontcolor(color: string): string 107 | 108 | /** Returns a HTML element and sets the size attribute value */ 109 | fontsize(size: number): string; 110 | 111 | /** Returns a HTML element and sets the size attribute value */ 112 | fontsize(size: string): string; 113 | 114 | /** Returns an HTML element */ 115 | italics(): string; 116 | 117 | /** Returns an HTML element and sets the href attribute value */ 118 | link(url: string): string; 119 | 120 | /** Returns a HTML element */ 121 | small(): string; 122 | 123 | /** Returns a HTML element */ 124 | strike(): string; 125 | 126 | /** Returns a HTML element */ 127 | sub(): string; 128 | 129 | /** Returns a HTML element */ 130 | sup(): string; 131 | 132 | /** 133 | * Shim for an ES6 iterable. Not intended for direct use by user code. 134 | */ 135 | "_es6-shim iterator_"(): IterableIteratorShim; 136 | } 137 | 138 | interface ArrayConstructor { 139 | /** 140 | * Creates an array from an array-like object. 141 | * @param arrayLike An array-like object to convert to an array. 142 | * @param mapfn A mapping function to call on every element of the array. 143 | * @param thisArg Value of 'this' used to invoke the mapfn. 144 | */ 145 | from(arrayLike: ArrayLike, mapfn: (v: T, k: number) => U, thisArg?: any): Array; 146 | 147 | /** 148 | * Creates an array from an iterable object. 149 | * @param iterable An iterable object to convert to an array. 150 | * @param mapfn A mapping function to call on every element of the array. 151 | * @param thisArg Value of 'this' used to invoke the mapfn. 152 | */ 153 | from(iterable: IterableShim, mapfn: (v: T, k: number) => U, thisArg?: any): Array; 154 | 155 | /** 156 | * Creates an array from an array-like object. 157 | * @param arrayLike An array-like object to convert to an array. 158 | */ 159 | from(arrayLike: ArrayLike): Array; 160 | 161 | /** 162 | * Creates an array from an iterable object. 163 | * @param iterable An iterable object to convert to an array. 164 | */ 165 | from(iterable: IterableShim): Array; 166 | 167 | /** 168 | * Returns a new array from a set of elements. 169 | * @param items A set of elements to include in the new array object. 170 | */ 171 | of(...items: T[]): Array; 172 | } 173 | 174 | interface Array { 175 | /** 176 | * Returns the value of the first element in the array where predicate is true, and undefined 177 | * otherwise. 178 | * @param predicate find calls predicate once for each element of the array, in ascending 179 | * order, until it finds one where predicate returns true. If such an element is found, find 180 | * immediately returns that element value. Otherwise, find returns undefined. 181 | * @param thisArg If provided, it will be used as the this value for each invocation of 182 | * predicate. If it is not provided, undefined is used instead. 183 | */ 184 | find(predicate: (value: T, index: number, obj: Array) => boolean, thisArg?: any): T; 185 | 186 | /** 187 | * Returns the index of the first element in the array where predicate is true, and undefined 188 | * otherwise. 189 | * @param predicate find calls predicate once for each element of the array, in ascending 190 | * order, until it finds one where predicate returns true. If such an element is found, find 191 | * immediately returns that element value. Otherwise, find returns undefined. 192 | * @param thisArg If provided, it will be used as the this value for each invocation of 193 | * predicate. If it is not provided, undefined is used instead. 194 | */ 195 | findIndex(predicate: (value: T) => boolean, thisArg?: any): number; 196 | 197 | /** 198 | * Returns the this object after filling the section identified by start and end with value 199 | * @param value value to fill array section with 200 | * @param start index to start filling the array at. If start is negative, it is treated as 201 | * length+start where length is the length of the array. 202 | * @param end index to stop filling the array at. If end is negative, it is treated as 203 | * length+end. 204 | */ 205 | fill(value: T, start?: number, end?: number): T[]; 206 | 207 | /** 208 | * Returns the this object after copying a section of the array identified by start and end 209 | * to the same array starting at position target 210 | * @param target If target is negative, it is treated as length+target where length is the 211 | * length of the array. 212 | * @param start If start is negative, it is treated as length+start. If end is negative, it 213 | * is treated as length+end. 214 | * @param end If not specified, length of the this object is used as its default value. 215 | */ 216 | copyWithin(target: number, start: number, end?: number): T[]; 217 | 218 | /** 219 | * Returns an array of key, value pairs for every entry in the array 220 | */ 221 | entries(): IterableIteratorShim<[number, T]>; 222 | 223 | /** 224 | * Returns an list of keys in the array 225 | */ 226 | keys(): IterableIteratorShim; 227 | 228 | /** 229 | * Returns an list of values in the array 230 | */ 231 | values(): IterableIteratorShim; 232 | 233 | /** 234 | * Shim for an ES6 iterable. Not intended for direct use by user code. 235 | */ 236 | "_es6-shim iterator_"(): IterableIteratorShim; 237 | } 238 | 239 | interface NumberConstructor { 240 | /** 241 | * The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1 242 | * that is representable as a Number value, which is approximately: 243 | * 2.2204460492503130808472633361816 x 10‍−‍16. 244 | */ 245 | EPSILON: number; 246 | 247 | /** 248 | * Returns true if passed value is finite. 249 | * Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a 250 | * number. Only finite values of the type number, result in true. 251 | * @param number A numeric value. 252 | */ 253 | isFinite(number: number): boolean; 254 | 255 | /** 256 | * Returns true if the value passed is an integer, false otherwise. 257 | * @param number A numeric value. 258 | */ 259 | isInteger(number: number): boolean; 260 | 261 | /** 262 | * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a 263 | * number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter 264 | * to a number. Only values of the type number, that are also NaN, result in true. 265 | * @param number A numeric value. 266 | */ 267 | isNaN(number: number): boolean; 268 | 269 | /** 270 | * Returns true if the value passed is a safe integer. 271 | * @param number A numeric value. 272 | */ 273 | isSafeInteger(number: number): boolean; 274 | 275 | /** 276 | * The value of the largest integer n such that n and n + 1 are both exactly representable as 277 | * a Number value. 278 | * The value of Number.MIN_SAFE_INTEGER is 9007199254740991 2^53 − 1. 279 | */ 280 | MAX_SAFE_INTEGER: number; 281 | 282 | /** 283 | * The value of the smallest integer n such that n and n − 1 are both exactly representable as 284 | * a Number value. 285 | * The value of Number.MIN_SAFE_INTEGER is −9007199254740991 (−(2^53 − 1)). 286 | */ 287 | MIN_SAFE_INTEGER: number; 288 | 289 | /** 290 | * Converts a string to a floating-point number. 291 | * @param string A string that contains a floating-point number. 292 | */ 293 | parseFloat(string: string): number; 294 | 295 | /** 296 | * Converts A string to an integer. 297 | * @param s A string to convert into a number. 298 | * @param radix A value between 2 and 36 that specifies the base of the number in numString. 299 | * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. 300 | * All other strings are considered decimal. 301 | */ 302 | parseInt(string: string, radix?: number): number; 303 | } 304 | 305 | interface ObjectConstructor { 306 | /** 307 | * Copy the values of all of the enumerable own properties from one or more source objects to a 308 | * target object. Returns the target object. 309 | * @param target The target object to copy to. 310 | * @param sources One or more source objects to copy properties from. 311 | */ 312 | assign(target: any, ...sources: any[]): any; 313 | 314 | /** 315 | * Returns true if the values are the same value, false otherwise. 316 | * @param value1 The first value. 317 | * @param value2 The second value. 318 | */ 319 | is(value1: any, value2: any): boolean; 320 | 321 | /** 322 | * Sets the prototype of a specified object o to object proto or null. Returns the object o. 323 | * @param o The object to change its prototype. 324 | * @param proto The value of the new prototype or null. 325 | * @remarks Requires `__proto__` support. 326 | */ 327 | setPrototypeOf(o: any, proto: any): any; 328 | } 329 | 330 | interface RegExp { 331 | /** 332 | * Returns a string indicating the flags of the regular expression in question. This field is read-only. 333 | * The characters in this string are sequenced and concatenated in the following order: 334 | * 335 | * - "g" for global 336 | * - "i" for ignoreCase 337 | * - "m" for multiline 338 | * - "u" for unicode 339 | * - "y" for sticky 340 | * 341 | * If no flags are set, the value is the empty string. 342 | */ 343 | flags: string; 344 | } 345 | 346 | interface Math { 347 | /** 348 | * Returns the number of leading zero bits in the 32-bit binary representation of a number. 349 | * @param x A numeric expression. 350 | */ 351 | clz32(x: number): number; 352 | 353 | /** 354 | * Returns the result of 32-bit multiplication of two numbers. 355 | * @param x First number 356 | * @param y Second number 357 | */ 358 | imul(x: number, y: number): number; 359 | 360 | /** 361 | * Returns the sign of the x, indicating whether x is positive, negative or zero. 362 | * @param x The numeric expression to test 363 | */ 364 | sign(x: number): number; 365 | 366 | /** 367 | * Returns the base 10 logarithm of a number. 368 | * @param x A numeric expression. 369 | */ 370 | log10(x: number): number; 371 | 372 | /** 373 | * Returns the base 2 logarithm of a number. 374 | * @param x A numeric expression. 375 | */ 376 | log2(x: number): number; 377 | 378 | /** 379 | * Returns the natural logarithm of 1 + x. 380 | * @param x A numeric expression. 381 | */ 382 | log1p(x: number): number; 383 | 384 | /** 385 | * Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of 386 | * the natural logarithms). 387 | * @param x A numeric expression. 388 | */ 389 | expm1(x: number): number; 390 | 391 | /** 392 | * Returns the hyperbolic cosine of a number. 393 | * @param x A numeric expression that contains an angle measured in radians. 394 | */ 395 | cosh(x: number): number; 396 | 397 | /** 398 | * Returns the hyperbolic sine of a number. 399 | * @param x A numeric expression that contains an angle measured in radians. 400 | */ 401 | sinh(x: number): number; 402 | 403 | /** 404 | * Returns the hyperbolic tangent of a number. 405 | * @param x A numeric expression that contains an angle measured in radians. 406 | */ 407 | tanh(x: number): number; 408 | 409 | /** 410 | * Returns the inverse hyperbolic cosine of a number. 411 | * @param x A numeric expression that contains an angle measured in radians. 412 | */ 413 | acosh(x: number): number; 414 | 415 | /** 416 | * Returns the inverse hyperbolic sine of a number. 417 | * @param x A numeric expression that contains an angle measured in radians. 418 | */ 419 | asinh(x: number): number; 420 | 421 | /** 422 | * Returns the inverse hyperbolic tangent of a number. 423 | * @param x A numeric expression that contains an angle measured in radians. 424 | */ 425 | atanh(x: number): number; 426 | 427 | /** 428 | * Returns the square root of the sum of squares of its arguments. 429 | * @param values Values to compute the square root for. 430 | * If no arguments are passed, the result is +0. 431 | * If there is only one argument, the result is the absolute value. 432 | * If any argument is +Infinity or -Infinity, the result is +Infinity. 433 | * If any argument is NaN, the result is NaN. 434 | * If all arguments are either +0 or −0, the result is +0. 435 | */ 436 | hypot(...values: number[]): number; 437 | 438 | /** 439 | * Returns the integral part of the a numeric expression, x, removing any fractional digits. 440 | * If x is already an integer, the result is x. 441 | * @param x A numeric expression. 442 | */ 443 | trunc(x: number): number; 444 | 445 | /** 446 | * Returns the nearest single precision float representation of a number. 447 | * @param x A numeric expression. 448 | */ 449 | fround(x: number): number; 450 | 451 | /** 452 | * Returns an implementation-dependent approximation to the cube root of number. 453 | * @param x A numeric expression. 454 | */ 455 | cbrt(x: number): number; 456 | } 457 | 458 | interface PromiseLike { 459 | /** 460 | * Attaches callbacks for the resolution and/or rejection of the Promise. 461 | * @param onfulfilled The callback to execute when the Promise is resolved. 462 | * @param onrejected The callback to execute when the Promise is rejected. 463 | * @returns A Promise for the completion of which ever callback is executed. 464 | */ 465 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): PromiseLike; 466 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): PromiseLike; 467 | } 468 | 469 | /** 470 | * Represents the completion of an asynchronous operation 471 | */ 472 | interface Promise { 473 | /** 474 | * Attaches callbacks for the resolution and/or rejection of the Promise. 475 | * @param onfulfilled The callback to execute when the Promise is resolved. 476 | * @param onrejected The callback to execute when the Promise is rejected. 477 | * @returns A Promise for the completion of which ever callback is executed. 478 | */ 479 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => TResult | PromiseLike): Promise; 480 | then(onfulfilled?: (value: T) => TResult | PromiseLike, onrejected?: (reason: any) => void): Promise; 481 | 482 | /** 483 | * Attaches a callback for only the rejection of the Promise. 484 | * @param onrejected The callback to execute when the Promise is rejected. 485 | * @returns A Promise for the completion of the callback. 486 | */ 487 | catch(onrejected?: (reason: any) => T | PromiseLike): Promise; 488 | catch(onrejected?: (reason: any) => void): Promise; 489 | } 490 | 491 | interface PromiseConstructor { 492 | /** 493 | * A reference to the prototype. 494 | */ 495 | prototype: Promise; 496 | 497 | /** 498 | * Creates a new Promise. 499 | * @param executor A callback used to initialize the promise. This callback is passed two arguments: 500 | * a resolve callback used resolve the promise with a value or the result of another promise, 501 | * and a reject callback used to reject the promise with a provided reason or error. 502 | */ 503 | new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; 504 | 505 | /** 506 | * Creates a Promise that is resolved with an array of results when all of the provided Promises 507 | * resolve, or rejected when any Promise is rejected. 508 | * @param values An array of Promises. 509 | * @returns A new Promise. 510 | */ 511 | all(values: IterableShim>): Promise; 512 | 513 | /** 514 | * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 515 | * or rejected. 516 | * @param values An array of Promises. 517 | * @returns A new Promise. 518 | */ 519 | race(values: IterableShim>): Promise; 520 | 521 | /** 522 | * Creates a new rejected promise for the provided reason. 523 | * @param reason The reason the promise was rejected. 524 | * @returns A new rejected Promise. 525 | */ 526 | reject(reason: any): Promise; 527 | 528 | /** 529 | * Creates a new rejected promise for the provided reason. 530 | * @param reason The reason the promise was rejected. 531 | * @returns A new rejected Promise. 532 | */ 533 | reject(reason: any): Promise; 534 | 535 | /** 536 | * Creates a new resolved promise for the provided value. 537 | * @param value A promise. 538 | * @returns A promise whose internal state matches the provided promise. 539 | */ 540 | resolve(value: T | PromiseLike): Promise; 541 | 542 | /** 543 | * Creates a new resolved promise . 544 | * @returns A resolved promise. 545 | */ 546 | resolve(): Promise; 547 | } 548 | 549 | declare var Promise: PromiseConstructor; 550 | 551 | interface Map { 552 | clear(): void; 553 | delete(key: K): boolean; 554 | forEach(callbackfn: (value: V, index: K, map: Map) => void, thisArg?: any): void; 555 | get(key: K): V; 556 | has(key: K): boolean; 557 | set(key: K, value?: V): Map; 558 | size: number; 559 | entries(): IterableIteratorShim<[K, V]>; 560 | keys(): IterableIteratorShim; 561 | values(): IterableIteratorShim; 562 | } 563 | 564 | interface MapConstructor { 565 | new (): Map; 566 | new (iterable: IterableShim<[K, V]>): Map; 567 | prototype: Map; 568 | } 569 | 570 | declare var Map: MapConstructor; 571 | 572 | interface Set { 573 | add(value: T): Set; 574 | clear(): void; 575 | delete(value: T): boolean; 576 | forEach(callbackfn: (value: T, index: T, set: Set) => void, thisArg?: any): void; 577 | has(value: T): boolean; 578 | size: number; 579 | entries(): IterableIteratorShim<[T, T]>; 580 | keys(): IterableIteratorShim; 581 | values(): IterableIteratorShim; 582 | '_es6-shim iterator_'(): IterableIteratorShim; 583 | } 584 | 585 | interface SetConstructor { 586 | new (): Set; 587 | new (iterable: IterableShim): Set; 588 | prototype: Set; 589 | } 590 | 591 | declare var Set: SetConstructor; 592 | 593 | interface WeakMap { 594 | delete(key: K): boolean; 595 | get(key: K): V; 596 | has(key: K): boolean; 597 | set(key: K, value?: V): WeakMap; 598 | } 599 | 600 | interface WeakMapConstructor { 601 | new (): WeakMap; 602 | new (iterable: IterableShim<[K, V]>): WeakMap; 603 | prototype: WeakMap; 604 | } 605 | 606 | declare var WeakMap: WeakMapConstructor; 607 | 608 | interface WeakSet { 609 | add(value: T): WeakSet; 610 | delete(value: T): boolean; 611 | has(value: T): boolean; 612 | } 613 | 614 | interface WeakSetConstructor { 615 | new (): WeakSet; 616 | new (iterable: IterableShim): WeakSet; 617 | prototype: WeakSet; 618 | } 619 | 620 | declare var WeakSet: WeakSetConstructor; 621 | 622 | declare namespace Reflect { 623 | function apply(target: Function, thisArgument: any, argumentsList: ArrayLike): any; 624 | function construct(target: Function, argumentsList: ArrayLike): any; 625 | function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean; 626 | function deleteProperty(target: any, propertyKey: PropertyKey): boolean; 627 | function enumerate(target: any): IterableIteratorShim; 628 | function get(target: any, propertyKey: PropertyKey, receiver?: any): any; 629 | function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor; 630 | function getPrototypeOf(target: any): any; 631 | function has(target: any, propertyKey: PropertyKey): boolean; 632 | function isExtensible(target: any): boolean; 633 | function ownKeys(target: any): Array; 634 | function preventExtensions(target: any): boolean; 635 | function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean; 636 | function setPrototypeOf(target: any, proto: any): boolean; 637 | } 638 | 639 | declare module "es6-shim" { 640 | var String: StringConstructor; 641 | var Array: ArrayConstructor; 642 | var Number: NumberConstructor; 643 | var Math: Math; 644 | var Object: ObjectConstructor; 645 | var Map: MapConstructor; 646 | var Set: SetConstructor; 647 | var WeakMap: WeakMapConstructor; 648 | var WeakSet: WeakSetConstructor; 649 | var Promise: PromiseConstructor; 650 | namespace Reflect { 651 | function apply(target: Function, thisArgument: any, argumentsList: ArrayLike): any; 652 | function construct(target: Function, argumentsList: ArrayLike): any; 653 | function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean; 654 | function deleteProperty(target: any, propertyKey: PropertyKey): boolean; 655 | function enumerate(target: any): Iterator; 656 | function get(target: any, propertyKey: PropertyKey, receiver?: any): any; 657 | function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor; 658 | function getPrototypeOf(target: any): any; 659 | function has(target: any, propertyKey: PropertyKey): boolean; 660 | function isExtensible(target: any): boolean; 661 | function ownKeys(target: any): Array; 662 | function preventExtensions(target: any): boolean; 663 | function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean; 664 | function setPrototypeOf(target: any, proto: any): boolean; 665 | } 666 | } 667 | -------------------------------------------------------------------------------- /typings/globals/es6-shim/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/9807d9b701f58be068cb07833d2b24235351d052/es6-shim/es6-shim.d.ts", 5 | "raw": "registry:dt/es6-shim#0.31.2+20160602141504", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/9807d9b701f58be068cb07833d2b24235351d052/es6-shim/es6-shim.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/globals/webrtc/mediastream/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/webrtc/MediaStream.d.ts 3 | interface ConstrainBooleanParameters { 4 | exact?: boolean; 5 | ideal?: boolean; 6 | } 7 | 8 | interface NumberRange { 9 | max?: number; 10 | min?: number; 11 | } 12 | 13 | interface ConstrainNumberRange extends NumberRange { 14 | exact?: number; 15 | ideal?: number; 16 | } 17 | 18 | interface ConstrainStringParameters { 19 | exact?: string | string[]; 20 | ideal?: string | string[]; 21 | } 22 | 23 | interface MediaStreamConstraints { 24 | video?: boolean | MediaTrackConstraints; 25 | audio?: boolean | MediaTrackConstraints; 26 | } 27 | 28 | declare namespace W3C { 29 | type LongRange = NumberRange; 30 | type DoubleRange = NumberRange; 31 | type ConstrainBoolean = boolean | ConstrainBooleanParameters; 32 | type ConstrainNumber = number | ConstrainNumberRange; 33 | type ConstrainLong = ConstrainNumber; 34 | type ConstrainDouble = ConstrainNumber; 35 | type ConstrainString = string | string[] | ConstrainStringParameters; 36 | } 37 | 38 | interface MediaTrackConstraints extends MediaTrackConstraintSet { 39 | advanced?: MediaTrackConstraintSet[]; 40 | } 41 | 42 | interface MediaTrackConstraintSet { 43 | width?: W3C.ConstrainLong; 44 | height?: W3C.ConstrainLong; 45 | aspectRatio?: W3C.ConstrainDouble; 46 | frameRate?: W3C.ConstrainDouble; 47 | facingMode?: W3C.ConstrainString; 48 | volume?: W3C.ConstrainDouble; 49 | sampleRate?: W3C.ConstrainLong; 50 | sampleSize?: W3C.ConstrainLong; 51 | echoCancellation?: W3C.ConstrainBoolean; 52 | latency?: W3C.ConstrainDouble; 53 | deviceId?: W3C.ConstrainString; 54 | groupId?: W3C.ConstrainString; 55 | } 56 | 57 | interface MediaTrackSupportedConstraints { 58 | width?: boolean; 59 | height?: boolean; 60 | aspectRatio?: boolean; 61 | frameRate?: boolean; 62 | facingMode?: boolean; 63 | volume?: boolean; 64 | sampleRate?: boolean; 65 | sampleSize?: boolean; 66 | echoCancellation?: boolean; 67 | latency?: boolean; 68 | deviceId?: boolean; 69 | groupId?: boolean; 70 | } 71 | 72 | interface MediaStream extends EventTarget { 73 | id: string; 74 | active: boolean; 75 | 76 | onactive: EventListener; 77 | oninactive: EventListener; 78 | onaddtrack: (event: MediaStreamTrackEvent) => any; 79 | onremovetrack: (event: MediaStreamTrackEvent) => any; 80 | 81 | clone(): MediaStream; 82 | stop(): void; 83 | 84 | getAudioTracks(): MediaStreamTrack[]; 85 | getVideoTracks(): MediaStreamTrack[]; 86 | getTracks(): MediaStreamTrack[]; 87 | 88 | getTrackById(trackId: string): MediaStreamTrack; 89 | 90 | addTrack(track: MediaStreamTrack): void; 91 | removeTrack(track: MediaStreamTrack): void; 92 | } 93 | 94 | interface MediaStreamTrackEvent extends Event { 95 | track: MediaStreamTrack; 96 | } 97 | 98 | declare enum MediaStreamTrackState { 99 | "live", 100 | "ended" 101 | } 102 | 103 | interface MediaStreamTrack extends EventTarget { 104 | id: string; 105 | kind: string; 106 | label: string; 107 | enabled: boolean; 108 | muted: boolean; 109 | remote: boolean; 110 | readyState: MediaStreamTrackState; 111 | 112 | onmute: EventListener; 113 | onunmute: EventListener; 114 | onended: EventListener; 115 | onoverconstrained: EventListener; 116 | 117 | clone(): MediaStreamTrack; 118 | 119 | stop(): void; 120 | 121 | getCapabilities(): MediaTrackCapabilities; 122 | getConstraints(): MediaTrackConstraints; 123 | getSettings(): MediaTrackSettings; 124 | applyConstraints(constraints: MediaTrackConstraints): Promise; 125 | } 126 | 127 | interface MediaTrackCapabilities { 128 | width: number | W3C.LongRange; 129 | height: number | W3C.LongRange; 130 | aspectRatio: number | W3C.DoubleRange; 131 | frameRate: number | W3C.DoubleRange; 132 | facingMode: string; 133 | volume: number | W3C.DoubleRange; 134 | sampleRate: number | W3C.LongRange; 135 | sampleSize: number | W3C.LongRange; 136 | echoCancellation: boolean[]; 137 | latency: number | W3C.DoubleRange; 138 | deviceId: string; 139 | groupId: string; 140 | } 141 | 142 | interface MediaTrackSettings { 143 | width: number; 144 | height: number; 145 | aspectRatio: number; 146 | frameRate: number; 147 | facingMode: string; 148 | volume: number; 149 | sampleRate: number; 150 | sampleSize: number; 151 | echoCancellation: boolean; 152 | latency: number; 153 | deviceId: string; 154 | groupId: string; 155 | } 156 | 157 | interface MediaStreamError { 158 | name: string; 159 | message: string; 160 | constraintName: string; 161 | } 162 | 163 | interface NavigatorGetUserMedia { 164 | (constraints: MediaStreamConstraints, 165 | successCallback: (stream: MediaStream) => void, 166 | errorCallback: (error: MediaStreamError) => void): void; 167 | } 168 | 169 | // to use with adapter.js, see: https://github.com/webrtc/adapter 170 | declare var getUserMedia: NavigatorGetUserMedia; 171 | 172 | interface Navigator { 173 | getUserMedia: NavigatorGetUserMedia; 174 | 175 | webkitGetUserMedia: NavigatorGetUserMedia; 176 | 177 | mozGetUserMedia: NavigatorGetUserMedia; 178 | 179 | msGetUserMedia: NavigatorGetUserMedia; 180 | 181 | mediaDevices: MediaDevices; 182 | } 183 | 184 | interface MediaDevices { 185 | getSupportedConstraints(): MediaTrackSupportedConstraints; 186 | 187 | getUserMedia(constraints: MediaStreamConstraints): Promise; 188 | enumerateDevices(): Promise; 189 | } 190 | 191 | interface MediaDeviceInfo { 192 | label: string; 193 | deviceId: string; 194 | kind: string; 195 | groupId: string; 196 | } 197 | -------------------------------------------------------------------------------- /typings/globals/webrtc/mediastream/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/webrtc/MediaStream.d.ts", 5 | "raw": "registry:dt/webrtc/mediastream#0.0.0+20160317120654", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/webrtc/MediaStream.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /typings/main.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /typings/main/ambient/webrtc/mediastream/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/webrtc/MediaStream.d.ts 3 | // Type definitions for WebRTC 4 | // Project: http://dev.w3.org/2011/webrtc/ 5 | // Definitions by: Ken Smith 6 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 7 | 8 | // Taken from http://dev.w3.org/2011/webrtc/editor/getusermedia.html 9 | // version: W3C Editor's Draft 29 June 2015 10 | 11 | interface ConstrainBooleanParameters { 12 | exact?: boolean; 13 | ideal?: boolean; 14 | } 15 | 16 | interface NumberRange { 17 | max?: number; 18 | min?: number; 19 | } 20 | 21 | interface ConstrainNumberRange extends NumberRange { 22 | exact?: number; 23 | ideal?: number; 24 | } 25 | 26 | interface ConstrainStringParameters { 27 | exact?: string | string[]; 28 | ideal?: string | string[]; 29 | } 30 | 31 | interface MediaStreamConstraints { 32 | video?: boolean | MediaTrackConstraints; 33 | audio?: boolean | MediaTrackConstraints; 34 | } 35 | 36 | declare namespace W3C { 37 | type LongRange = NumberRange; 38 | type DoubleRange = NumberRange; 39 | type ConstrainBoolean = boolean | ConstrainBooleanParameters; 40 | type ConstrainNumber = number | ConstrainNumberRange; 41 | type ConstrainLong = ConstrainNumber; 42 | type ConstrainDouble = ConstrainNumber; 43 | type ConstrainString = string | string[] | ConstrainStringParameters; 44 | } 45 | 46 | interface MediaTrackConstraints extends MediaTrackConstraintSet { 47 | advanced?: MediaTrackConstraintSet[]; 48 | } 49 | 50 | interface MediaTrackConstraintSet { 51 | width?: W3C.ConstrainLong; 52 | height?: W3C.ConstrainLong; 53 | aspectRatio?: W3C.ConstrainDouble; 54 | frameRate?: W3C.ConstrainDouble; 55 | facingMode?: W3C.ConstrainString; 56 | volume?: W3C.ConstrainDouble; 57 | sampleRate?: W3C.ConstrainLong; 58 | sampleSize?: W3C.ConstrainLong; 59 | echoCancellation?: W3C.ConstrainBoolean; 60 | latency?: W3C.ConstrainDouble; 61 | deviceId?: W3C.ConstrainString; 62 | groupId?: W3C.ConstrainString; 63 | } 64 | 65 | interface MediaTrackSupportedConstraints { 66 | width?: boolean; 67 | height?: boolean; 68 | aspectRatio?: boolean; 69 | frameRate?: boolean; 70 | facingMode?: boolean; 71 | volume?: boolean; 72 | sampleRate?: boolean; 73 | sampleSize?: boolean; 74 | echoCancellation?: boolean; 75 | latency?: boolean; 76 | deviceId?: boolean; 77 | groupId?: boolean; 78 | } 79 | 80 | interface MediaStream extends EventTarget { 81 | id: string; 82 | active: boolean; 83 | 84 | onactive: EventListener; 85 | oninactive: EventListener; 86 | onaddtrack: (event: MediaStreamTrackEvent) => any; 87 | onremovetrack: (event: MediaStreamTrackEvent) => any; 88 | 89 | clone(): MediaStream; 90 | stop(): void; 91 | 92 | getAudioTracks(): MediaStreamTrack[]; 93 | getVideoTracks(): MediaStreamTrack[]; 94 | getTracks(): MediaStreamTrack[]; 95 | 96 | getTrackById(trackId: string): MediaStreamTrack; 97 | 98 | addTrack(track: MediaStreamTrack): void; 99 | removeTrack(track: MediaStreamTrack): void; 100 | } 101 | 102 | interface MediaStreamTrackEvent extends Event { 103 | track: MediaStreamTrack; 104 | } 105 | 106 | declare enum MediaStreamTrackState { 107 | "live", 108 | "ended" 109 | } 110 | 111 | interface MediaStreamTrack extends EventTarget { 112 | id: string; 113 | kind: string; 114 | label: string; 115 | enabled: boolean; 116 | muted: boolean; 117 | remote: boolean; 118 | readyState: MediaStreamTrackState; 119 | 120 | onmute: EventListener; 121 | onunmute: EventListener; 122 | onended: EventListener; 123 | onoverconstrained: EventListener; 124 | 125 | clone(): MediaStreamTrack; 126 | 127 | stop(): void; 128 | 129 | getCapabilities(): MediaTrackCapabilities; 130 | getConstraints(): MediaTrackConstraints; 131 | getSettings(): MediaTrackSettings; 132 | applyConstraints(constraints: MediaTrackConstraints): Promise; 133 | } 134 | 135 | interface MediaTrackCapabilities { 136 | width: number | W3C.LongRange; 137 | height: number | W3C.LongRange; 138 | aspectRatio: number | W3C.DoubleRange; 139 | frameRate: number | W3C.DoubleRange; 140 | facingMode: string; 141 | volume: number | W3C.DoubleRange; 142 | sampleRate: number | W3C.LongRange; 143 | sampleSize: number | W3C.LongRange; 144 | echoCancellation: boolean[]; 145 | latency: number | W3C.DoubleRange; 146 | deviceId: string; 147 | groupId: string; 148 | } 149 | 150 | interface MediaTrackSettings { 151 | width: number; 152 | height: number; 153 | aspectRatio: number; 154 | frameRate: number; 155 | facingMode: string; 156 | volume: number; 157 | sampleRate: number; 158 | sampleSize: number; 159 | echoCancellation: boolean; 160 | latency: number; 161 | deviceId: string; 162 | groupId: string; 163 | } 164 | 165 | interface MediaStreamError { 166 | name: string; 167 | message: string; 168 | constraintName: string; 169 | } 170 | 171 | interface NavigatorGetUserMedia { 172 | (constraints: MediaStreamConstraints, 173 | successCallback: (stream: MediaStream) => void, 174 | errorCallback: (error: MediaStreamError) => void): void; 175 | } 176 | 177 | // to use with adapter.js, see: https://github.com/webrtc/adapter 178 | declare var getUserMedia: NavigatorGetUserMedia; 179 | 180 | interface Navigator { 181 | getUserMedia: NavigatorGetUserMedia; 182 | 183 | webkitGetUserMedia: NavigatorGetUserMedia; 184 | 185 | mozGetUserMedia: NavigatorGetUserMedia; 186 | 187 | msGetUserMedia: NavigatorGetUserMedia; 188 | 189 | mediaDevices: MediaDevices; 190 | } 191 | 192 | interface MediaDevices { 193 | getSupportedConstraints(): MediaTrackSupportedConstraints; 194 | 195 | getUserMedia(constraints: MediaStreamConstraints): Promise; 196 | enumerateDevices(): Promise; 197 | } 198 | 199 | interface MediaDeviceInfo { 200 | label: string; 201 | deviceId: string; 202 | kind: string; 203 | groupId: string; 204 | } -------------------------------------------------------------------------------- /typings/main/definitions/annyang/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/theluk/typed-annyang/bcd191374316617db56f4737874e520a93ab6bf9/index.d.ts 3 | declare module '~annyang/index' { 4 | /** 5 | * Options for function `start` 6 | * 7 | * @export 8 | * @interface StartOptions 9 | */ 10 | export interface StartOptions { 11 | /** 12 | * Should annyang restart itself if it is closed indirectly, because of silence or window conflicts? 13 | * 14 | * @type {boolean} 15 | */ 16 | autoRestart? : boolean; 17 | /** 18 | * Allow forcing continuous mode on or off. Annyang is pretty smart about this, so only set this if you know what you're doing. 19 | * 20 | * @type {boolean} 21 | */ 22 | continuous? : boolean; 23 | } 24 | /** 25 | * A command option that supports custom regular expressions 26 | * 27 | * @export 28 | * @interface CommandOptionRegex 29 | */ 30 | export interface CommandOptionRegex { 31 | /** 32 | * @type {RegExp} 33 | */ 34 | regexp: RegExp; 35 | /** 36 | * @type {() => any} 37 | */ 38 | callback: () => void; 39 | } 40 | /** 41 | * Commands that annyang should listen to 42 | * 43 | * #### Examples: 44 | * ````javascript 45 | * {'hello :name': helloFunction, 'howdy': helloFunction}; 46 | * {'hi': helloFunction}; 47 | * ```` 48 | * @export 49 | * @interface CommandOption 50 | */ 51 | export interface CommandOption { 52 | [command:string]: CommandOptionRegex | (() => void); 53 | } 54 | /** 55 | * Supported Events that will be triggered to listeners, you attach using `annyang.addCallback()` 56 | * 57 | * `start` - Fired as soon as the browser's Speech Recognition engine starts listening 58 | * `error` - Fired when the browser's Speech Recogntion engine returns an error, this generic error callback will be followed by more accurate error callbacks (both will fire if both are defined) 59 | * `errorNetwork` - Fired when Speech Recognition fails because of a network error 60 | * `errorPermissionBlocked` - Fired when the browser blocks the permission request to use Speech Recognition. 61 | * `errorPermissionDenied` - Fired when the user blocks the permission request to use Speech Recognition. 62 | * `end` - Fired when the browser's Speech Recognition engine stops 63 | * `result` - Fired as soon as some speech was identified. This generic callback will be followed by either the `resultMatch` or `resultNoMatch` callbacks. 64 | * Callback functions registered to this event will include an array of possible phrases the user said as the first argument 65 | * `resultMatch` - Fired when annyang was able to match between what the user said and a registered command 66 | * Callback functions registered to this event will include three arguments in the following order: 67 | * * The phrase the user said that matched a command 68 | * * The command that was matched 69 | * * An array of possible alternative phrases the user might've said 70 | * `resultNoMatch` - Fired when what the user said didn't match any of the registered commands. 71 | * Callback functions registered to this event will include an array of possible phrases the user might've said as the first argument 72 | */ 73 | export type Events = "resultstart" | 74 | "error" | 75 | "end" | 76 | "result" | 77 | "resultMatch" | 78 | "resultNoMatch" | 79 | "errorNetwork" | 80 | "errorPermissionBlocked" | 81 | "errorPermissionDenied"; 82 | /** 83 | * Start listening. 84 | * It's a good idea to call this after adding some commands first, but not mandatory. 85 | * 86 | * @export 87 | * @param {StartOptions} options 88 | */ 89 | export function start(options : StartOptions) : void 90 | /** 91 | * Stop listening, and turn off mic. 92 | * 93 | * @export 94 | */ 95 | export function abort() : void 96 | /** 97 | * Pause listening. annyang will stop responding to commands (until the resume or start methods are called), without turning off the browser's SpeechRecognition engine or the mic. 98 | * 99 | * @export 100 | */ 101 | export function pause() : void 102 | /** 103 | * Resumes listening and restores command callback execution when a result matches. 104 | * If SpeechRecognition was aborted (stopped), start it. 105 | * 106 | * @export 107 | */ 108 | export function resume() : void 109 | /** 110 | * Turn on output of debug messages to the console. Ugly, but super-handy! 111 | * 112 | * @export 113 | * @param {boolean} [newState=true] Turn on/off debug messages 114 | */ 115 | export function debug(newState? : boolean) : void 116 | /** 117 | * Set the language the user will speak in. If this method is not called, defaults to 'en-US'. 118 | * 119 | * @export 120 | * @param {string} lang 121 | * @see [Languages](https://github.com/TalAter/annyang/blob/master/docs/FAQ.md#what-languages-are-supported) 122 | */ 123 | export function setLanguage(lang : string) : void 124 | /** 125 | * Add commands that annyang will respond to. Similar in syntax to init(), but doesn't remove existing commands. 126 | * 127 | * #### Examples: 128 | * ````javascript 129 | * var commands = {'hello :name': helloFunction, 'howdy': helloFunction}; 130 | * var commands2 = {'hi': helloFunction}; 131 | * 132 | * annyang.addCommands(commands); 133 | * annyang.addCommands(commands2); 134 | * // annyang will now listen to all three commands 135 | * ```` 136 | * 137 | * @export 138 | * @param {CommandOption} commands 139 | */ 140 | export function addCommands(commands : CommandOption) : void 141 | /** 142 | * Remove all existing commands. 143 | * 144 | * #### Examples: 145 | * ````javascript 146 | * var commands : annyang.CommandOption = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction}; 147 | * 148 | * // Remove all existing commands 149 | * annyang.removeCommands(); 150 | * ```` 151 | * @export 152 | */ 153 | export function removeCommands() : void 154 | /** 155 | * Removes a command 156 | * #### Examples: 157 | * ````javascript 158 | * // Don't respond to hello 159 | * annyang.removeCommands('hello'); 160 | * ```` 161 | * @export 162 | * @param {string} command 163 | */ 164 | export function removeCommands(command : string) : void 165 | /** 166 | * Removes a list of commands 167 | * #### Examples: 168 | * ````javascript 169 | * var commands : annyang.CommandOption = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction}; 170 | * // Add some commands 171 | * annyang.addCommands(commands); 172 | * // Don't respond to howdy or hi 173 | * annyang.removeCommands(['howdy', 'hi']); 174 | * ```` 175 | * 176 | * @export 177 | * @param {string[]} command 178 | */ 179 | export function removeCommands(command : string[]) : void 180 | /** 181 | * Add a callback function to be called, when a Event occures 182 | * 183 | * @export 184 | * @param {Events} event 185 | * @param {Function} callback 186 | * @param {*} [context] 187 | */ 188 | export function addCallback(event : Events, callback : () => void, context? : any) : void 189 | /** 190 | * Add a callback function to be called, when a Event occures 191 | * 192 | * @export 193 | * @param {Events} event 194 | * @param {(results : string[]) => void} callback 195 | * @param {*} [context] 196 | */ 197 | export function addCallback(event : Events, callback : (results : string[]) => void, context? : any) : void 198 | /** 199 | * @export 200 | * @param {Events} event 201 | * @param {(userSaid : string, commandText : string, results : string[]) => void} callback 202 | * @param {*} [context] 203 | */ 204 | export function addCallback(event : Events, callback : (userSaid : string, commandText : string, results : string[]) => void, context? : any) : void 205 | /** 206 | * @export 207 | * @param {Events} [event] 208 | * @param {Function} [callback] 209 | */ 210 | export function removeCallback(event? : Events, callback? : Function) : void 211 | /** 212 | * Returns true if speech recognition is currently on. 213 | * Returns false if speech recognition is off or annyang is paused. 214 | * 215 | * @export 216 | * @returns {boolean} 217 | */ 218 | export function isListening() : boolean 219 | /** 220 | * Returns the instance of the browser's SpeechRecognition object used by annyang. 221 | * Useful in case you want direct access to the browser's Speech Recognition engine. 222 | * 223 | * @export 224 | * @returns {*} 225 | */ 226 | export function getSpeechRecognizer() : any 227 | /** 228 | * Simulate speech being recognized. This will trigger the same events and behavior as when the Speech Recognition 229 | * detects speech. 230 | * 231 | * Can accept either a string containing a single sentence, or an array containing multiple sentences to be checked 232 | * in order until one of them matches a command (similar to the way Speech Recognition Alternatives are parsed) 233 | * 234 | * #### Examples: 235 | * ````javascript 236 | * annyang.trigger('Time for some thrilling heroics'); 237 | * annyang.trigger( 238 | * ['Time for some thrilling heroics', 'Time for some thrilling aerobics'] 239 | * ); 240 | * ```` 241 | * 242 | * @export 243 | * @param {string} command 244 | */ 245 | export function trigger(command : string) : void 246 | /** 247 | * @export 248 | * @param {string[]} command 249 | */ 250 | export function trigger(command : string[]) : void 251 | } 252 | declare module 'annyang/index' { 253 | export * from '~annyang/index'; 254 | } 255 | declare module 'annyang' { 256 | export * from '~annyang/index'; 257 | } 258 | -------------------------------------------------------------------------------- /typings/modules/annyang/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/theluk/typed-annyang/bcd191374316617db56f4737874e520a93ab6bf9/index.d.ts 3 | declare module 'annyang' { 4 | /** 5 | * Options for function `start` 6 | * 7 | * @export 8 | * @interface StartOptions 9 | */ 10 | export interface StartOptions { 11 | /** 12 | * Should annyang restart itself if it is closed indirectly, because of silence or window conflicts? 13 | * 14 | * @type {boolean} 15 | */ 16 | autoRestart? : boolean; 17 | /** 18 | * Allow forcing continuous mode on or off. Annyang is pretty smart about this, so only set this if you know what you're doing. 19 | * 20 | * @type {boolean} 21 | */ 22 | continuous? : boolean; 23 | } 24 | /** 25 | * A command option that supports custom regular expressions 26 | * 27 | * @export 28 | * @interface CommandOptionRegex 29 | */ 30 | export interface CommandOptionRegex { 31 | /** 32 | * @type {RegExp} 33 | */ 34 | regexp: RegExp; 35 | /** 36 | * @type {() => any} 37 | */ 38 | callback: () => void; 39 | } 40 | /** 41 | * Commands that annyang should listen to 42 | * 43 | * #### Examples: 44 | * ````javascript 45 | * {'hello :name': helloFunction, 'howdy': helloFunction}; 46 | * {'hi': helloFunction}; 47 | * ```` 48 | * @export 49 | * @interface CommandOption 50 | */ 51 | export interface CommandOption { 52 | [command:string]: CommandOptionRegex | (() => void); 53 | } 54 | /** 55 | * Supported Events that will be triggered to listeners, you attach using `annyang.addCallback()` 56 | * 57 | * `start` - Fired as soon as the browser's Speech Recognition engine starts listening 58 | * `error` - Fired when the browser's Speech Recogntion engine returns an error, this generic error callback will be followed by more accurate error callbacks (both will fire if both are defined) 59 | * `errorNetwork` - Fired when Speech Recognition fails because of a network error 60 | * `errorPermissionBlocked` - Fired when the browser blocks the permission request to use Speech Recognition. 61 | * `errorPermissionDenied` - Fired when the user blocks the permission request to use Speech Recognition. 62 | * `end` - Fired when the browser's Speech Recognition engine stops 63 | * `result` - Fired as soon as some speech was identified. This generic callback will be followed by either the `resultMatch` or `resultNoMatch` callbacks. 64 | * Callback functions registered to this event will include an array of possible phrases the user said as the first argument 65 | * `resultMatch` - Fired when annyang was able to match between what the user said and a registered command 66 | * Callback functions registered to this event will include three arguments in the following order: 67 | * * The phrase the user said that matched a command 68 | * * The command that was matched 69 | * * An array of possible alternative phrases the user might've said 70 | * `resultNoMatch` - Fired when what the user said didn't match any of the registered commands. 71 | * Callback functions registered to this event will include an array of possible phrases the user might've said as the first argument 72 | */ 73 | export type Events = "resultstart" | 74 | "error" | 75 | "end" | 76 | "result" | 77 | "resultMatch" | 78 | "resultNoMatch" | 79 | "errorNetwork" | 80 | "errorPermissionBlocked" | 81 | "errorPermissionDenied"; 82 | /** 83 | * Start listening. 84 | * It's a good idea to call this after adding some commands first, but not mandatory. 85 | * 86 | * @export 87 | * @param {StartOptions} options 88 | */ 89 | export function start(options : StartOptions) : void 90 | /** 91 | * Stop listening, and turn off mic. 92 | * 93 | * @export 94 | */ 95 | export function abort() : void 96 | /** 97 | * Pause listening. annyang will stop responding to commands (until the resume or start methods are called), without turning off the browser's SpeechRecognition engine or the mic. 98 | * 99 | * @export 100 | */ 101 | export function pause() : void 102 | /** 103 | * Resumes listening and restores command callback execution when a result matches. 104 | * If SpeechRecognition was aborted (stopped), start it. 105 | * 106 | * @export 107 | */ 108 | export function resume() : void 109 | /** 110 | * Turn on output of debug messages to the console. Ugly, but super-handy! 111 | * 112 | * @export 113 | * @param {boolean} [newState=true] Turn on/off debug messages 114 | */ 115 | export function debug(newState? : boolean) : void 116 | /** 117 | * Set the language the user will speak in. If this method is not called, defaults to 'en-US'. 118 | * 119 | * @export 120 | * @param {string} lang 121 | * @see [Languages](https://github.com/TalAter/annyang/blob/master/docs/FAQ.md#what-languages-are-supported) 122 | */ 123 | export function setLanguage(lang : string) : void 124 | /** 125 | * Add commands that annyang will respond to. Similar in syntax to init(), but doesn't remove existing commands. 126 | * 127 | * #### Examples: 128 | * ````javascript 129 | * var commands = {'hello :name': helloFunction, 'howdy': helloFunction}; 130 | * var commands2 = {'hi': helloFunction}; 131 | * 132 | * annyang.addCommands(commands); 133 | * annyang.addCommands(commands2); 134 | * // annyang will now listen to all three commands 135 | * ```` 136 | * 137 | * @export 138 | * @param {CommandOption} commands 139 | */ 140 | export function addCommands(commands : CommandOption) : void 141 | /** 142 | * Remove all existing commands. 143 | * 144 | * #### Examples: 145 | * ````javascript 146 | * var commands : annyang.CommandOption = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction}; 147 | * 148 | * // Remove all existing commands 149 | * annyang.removeCommands(); 150 | * ```` 151 | * @export 152 | */ 153 | export function removeCommands() : void 154 | /** 155 | * Removes a command 156 | * #### Examples: 157 | * ````javascript 158 | * // Don't respond to hello 159 | * annyang.removeCommands('hello'); 160 | * ```` 161 | * @export 162 | * @param {string} command 163 | */ 164 | export function removeCommands(command : string) : void 165 | /** 166 | * Removes a list of commands 167 | * #### Examples: 168 | * ````javascript 169 | * var commands : annyang.CommandOption = {'hello': helloFunction, 'howdy': helloFunction, 'hi': helloFunction}; 170 | * // Add some commands 171 | * annyang.addCommands(commands); 172 | * // Don't respond to howdy or hi 173 | * annyang.removeCommands(['howdy', 'hi']); 174 | * ```` 175 | * 176 | * @export 177 | * @param {string[]} command 178 | */ 179 | export function removeCommands(command : string[]) : void 180 | /** 181 | * Add a callback function to be called, when a Event occures 182 | * 183 | * @export 184 | * @param {Events} event 185 | * @param {Function} callback 186 | * @param {*} [context] 187 | */ 188 | export function addCallback(event : Events, callback : () => void, context? : any) : void 189 | /** 190 | * Add a callback function to be called, when a Event occures 191 | * 192 | * @export 193 | * @param {Events} event 194 | * @param {(results : string[]) => void} callback 195 | * @param {*} [context] 196 | */ 197 | export function addCallback(event : Events, callback : (results : string[]) => void, context? : any) : void 198 | /** 199 | * @export 200 | * @param {Events} event 201 | * @param {(userSaid : string, commandText : string, results : string[]) => void} callback 202 | * @param {*} [context] 203 | */ 204 | export function addCallback(event : Events, callback : (userSaid : string, commandText : string, results : string[]) => void, context? : any) : void 205 | /** 206 | * @export 207 | * @param {Events} [event] 208 | * @param {Function} [callback] 209 | */ 210 | export function removeCallback(event? : Events, callback? : Function) : void 211 | /** 212 | * Returns true if speech recognition is currently on. 213 | * Returns false if speech recognition is off or annyang is paused. 214 | * 215 | * @export 216 | * @returns {boolean} 217 | */ 218 | export function isListening() : boolean 219 | /** 220 | * Returns the instance of the browser's SpeechRecognition object used by annyang. 221 | * Useful in case you want direct access to the browser's Speech Recognition engine. 222 | * 223 | * @export 224 | * @returns {*} 225 | */ 226 | export function getSpeechRecognizer() : any 227 | /** 228 | * Simulate speech being recognized. This will trigger the same events and behavior as when the Speech Recognition 229 | * detects speech. 230 | * 231 | * Can accept either a string containing a single sentence, or an array containing multiple sentences to be checked 232 | * in order until one of them matches a command (similar to the way Speech Recognition Alternatives are parsed) 233 | * 234 | * #### Examples: 235 | * ````javascript 236 | * annyang.trigger('Time for some thrilling heroics'); 237 | * annyang.trigger( 238 | * ['Time for some thrilling heroics', 'Time for some thrilling aerobics'] 239 | * ); 240 | * ```` 241 | * 242 | * @export 243 | * @param {string} command 244 | */ 245 | export function trigger(command : string) : void 246 | /** 247 | * @export 248 | * @param {string[]} command 249 | */ 250 | export function trigger(command : string[]) : void 251 | } 252 | -------------------------------------------------------------------------------- /typings/modules/annyang/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/theluk/typed-annyang/bcd191374316617db56f4737874e520a93ab6bf9/typings.json", 5 | "raw": "registry:npm/annyang#2.4.0+20160507185443", 6 | "main": "index.d.ts", 7 | "version": "2.4.0", 8 | "global": false, 9 | "name": "annyang", 10 | "type": "typings" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /www/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found 6 | 71 | 72 | 73 |

Page Not Found

74 |

This specified file was not found on this website. Please check the URL for mistakes and try again.

75 |

Why am I seeing this?

76 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

77 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /www/CNAME: -------------------------------------------------------------------------------- 1 | https://angularlabs.2016.angularattack.io 2 | -------------------------------------------------------------------------------- /www/cordova.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/cordova.js -------------------------------------------------------------------------------- /www/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/favicon.png -------------------------------------------------------------------------------- /www/images/attila.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/attila.png -------------------------------------------------------------------------------- /www/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/icon.png -------------------------------------------------------------------------------- /www/images/letmesee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/letmesee.png -------------------------------------------------------------------------------- /www/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/logo.png -------------------------------------------------------------------------------- /www/images/ng-show.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/ng-show.mp3 -------------------------------------------------------------------------------- /www/images/pwa/android-chrome-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/android-chrome-36x36.png -------------------------------------------------------------------------------- /www/images/pwa/android-chrome-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/android-chrome-48x48.png -------------------------------------------------------------------------------- /www/images/pwa/android-chrome-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/android-chrome-72x72.png -------------------------------------------------------------------------------- /www/images/pwa/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/android-chrome-96x96.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /www/images/pwa/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/apple-touch-icon.png -------------------------------------------------------------------------------- /www/images/pwa/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #ffc40d 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /www/images/pwa/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/favicon-16x16.png -------------------------------------------------------------------------------- /www/images/pwa/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/favicon-32x32.png -------------------------------------------------------------------------------- /www/images/pwa/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/favicon-96x96.png -------------------------------------------------------------------------------- /www/images/pwa/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/favicon.ico -------------------------------------------------------------------------------- /www/images/pwa/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/icon.png -------------------------------------------------------------------------------- /www/images/pwa/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "en", 3 | "background_color": "#2c1a31", 4 | "theme_color": "#2c1a31", 5 | "name": "Let Me See", 6 | "short_name": "Let Me See", 7 | "icons": [ 8 | { 9 | "src": "images/pwa/android-chrome-36x36.png", 10 | "sizes": "36x36", 11 | "type": "image/png" 12 | }, 13 | { 14 | "src": "images/pwa/android-chrome-48x48.png", 15 | "sizes": "48x48", 16 | "type": "image/png" 17 | }, 18 | { 19 | "src": "images/pwa/android-chrome-72x72.png", 20 | "sizes": "72x72", 21 | "type": "image/png" 22 | }, 23 | { 24 | "src": "images/pwa/android-chrome-96x96.png", 25 | "sizes": "96x96", 26 | "type": "image/png" 27 | }, 28 | { 29 | "src": "images/pwa/icon.png", 30 | "sizes": "144x144", 31 | "type": "image/png" 32 | } 33 | ], 34 | "start_url": "/index.html", 35 | "display": "standalone", 36 | "orientation": "portrait" 37 | } 38 | -------------------------------------------------------------------------------- /www/images/pwa/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/mstile-150x150.png -------------------------------------------------------------------------------- /www/images/pwa/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/mstile-310x150.png -------------------------------------------------------------------------------- /www/images/pwa/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/pwa/mstile-70x70.png -------------------------------------------------------------------------------- /www/images/pwa/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 19 | 21 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /www/images/urish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/urish.png -------------------------------------------------------------------------------- /www/images/wassim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/manekinekko/angularattack2016/e3d3219c51decf85f2c50b5edb9f7fbc4755d84e/www/images/wassim.png -------------------------------------------------------------------------------- /www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Let Me See 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | Loading content... 45 | 46 | v1.1.38 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /www/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "en", 3 | "background_color": "#2c1a31", 4 | "theme_color": "#2c1a31", 5 | "name": "Let Me See", 6 | "short_name": "Let Me See", 7 | "display": "standalone", 8 | "start_url": "/index.html", 9 | "orientation": "portrait", 10 | "icons": [ 11 | { 12 | "src": "images/icon.png", 13 | "sizes": "144x144", 14 | "type": "image/png" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /www/sw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 Google Inc. All rights reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY! 18 | // This file should be overwritten as part of your build process. 19 | // If you need to extend the behavior of the generated service worker, the best approach is to write 20 | // additional code and include it using the importScripts option: 21 | // https://github.com/GoogleChrome/sw-precache#importscripts-arraystring 22 | // 23 | // Alternatively, it's possible to make changes to the underlying template file and then use that as the 24 | // new base for generating output, via the templateFilePath option: 25 | // https://github.com/GoogleChrome/sw-precache#templatefilepath-string 26 | // 27 | // If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any 28 | // changes made to this original template file with your modified copy. 29 | 30 | // This generated service worker JavaScript will precache your site's resources. 31 | // The code needs to be saved in a .js file at the top-level of your site, and registered 32 | // from your pages in order to be used. See 33 | // https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js 34 | // for an example of how you can register this script and handle various service worker events. 35 | 36 | /* eslint-env worker, serviceworker */ 37 | /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 38 | 'use strict'; 39 | 40 | var precacheConfig = [["404.html","b5a9c5870fb1e0409ae5a01cff0cf646"],["build/components/angie/angie.html","20142db44834a0c1512d48855bb3e6f0"],["build/css/app.ios.css","2a048a77730265e5080b9a43743b51d3"],["build/css/app.md.css","a6ce0df3fb008647b5e47fb7fb6dc389"],["build/css/app.wp.css","efe42bdc52182bdc5d6ce9584574beba"],["build/fonts/ionicons.ttf","74c652671225d6ded874a648502e5f0a"],["build/fonts/ionicons.woff","81414686e99c00d2921e03dd53c0ab04"],["build/fonts/ionicons.woff2","311d81961c5880647fec7eaca1221b2a"],["build/fonts/noto-sans-bold.ttf","a165a42685795361b25593effb32fdb1"],["build/fonts/noto-sans-regular.ttf","2fd9c16b805724d590c0cff96da070a4"],["build/fonts/roboto-bold.ttf","1f4fd7e4df65487f07ba9148f7ca095d"],["build/fonts/roboto-bold.woff","43183beef21370d8a4b0d64152287eba"],["build/fonts/roboto-light.ttf","9ff15bd34ea83e4dd3f23c20c7f5090e"],["build/fonts/roboto-light.woff","7e2d32e7141050d758a38b4ec96390c0"],["build/fonts/roboto-medium.ttf","a937e2cae14e68262a45aa91204c2fdf"],["build/fonts/roboto-medium.woff","0f3b7101a8adc1afe1fbe89775553c32"],["build/fonts/roboto-regular.ttf","07f8fb6acbabeb10d3fad9ab02d65e0b"],["build/fonts/roboto-regular.woff","f94d5e5102359961c44a1da1b58d37c9"],["build/js/Reflect.js","3e2f12c50659230feac24c06ecfa9f50"],["build/js/app.bundle.js","fe8c8c83f0b8eac59817c8e09669fadf"],["build/js/es6-shim.min.js","9d4304d9f51104986bc088e39fdf5d0d"],["build/js/zone.js","2222385d52aafe3cf4568d0173483fc6"],["build/pages/home/home.html","08c60cbbc05e2b37bb23dc5b28771e94"],["cordova.js","d41d8cd98f00b204e9800998ecf8427e"],["favicon.png","2d285ba901360c6e4a19af1a6d26d271"],["images/attila.png","6ff2d2ed69e3e12bf5cb7240c7dc8323"],["images/icon.png","d9802d1525f604c28cff0a7c84c27f35"],["images/letmesee.png","1caf22a67e203304da18f9331ab3d9ad"],["images/logo.png","488b9a9ccf745a64f442cdbdc08d5cf2"],["images/ng-show.mp3","a37c9ed9a87028ae5ff3bbd6633634cc"],["images/pwa/android-chrome-36x36.png","f2177d6683f1f15882d890de1a95bb62"],["images/pwa/android-chrome-48x48.png","9476b07e92718c92abfb2fac62f0a8b3"],["images/pwa/android-chrome-72x72.png","b8b2caa41e3bb170742997079bfa306b"],["images/pwa/android-chrome-96x96.png","c692f5b8705a974ebbda54d96872c190"],["images/pwa/apple-touch-icon-114x114.png","f9f12be465498a7bddab18cd9b7e673c"],["images/pwa/apple-touch-icon-120x120.png","f06d2444b7285ac69c51c178f98a912d"],["images/pwa/apple-touch-icon-57x57.png","f63093d3ff298e8be43c15955cf587de"],["images/pwa/apple-touch-icon-60x60.png","24136ec0c7a67cfb49d53450f6c623d6"],["images/pwa/apple-touch-icon-72x72.png","b5362e3c1a11a9bc387b92a1d3de0a41"],["images/pwa/apple-touch-icon-76x76.png","3dde2e009b6cc106583968b0439224e0"],["images/pwa/apple-touch-icon-precomposed.png","9bb93bc4070f2a6acd9152b9e0057d3d"],["images/pwa/apple-touch-icon.png","60dc6245bc876878dcc564b023c3184d"],["images/pwa/favicon-16x16.png","72026434d6ddaeadd99c370e725d7d7c"],["images/pwa/favicon-32x32.png","ff6c1a26ba6ff122d6e2d50c82ad8aca"],["images/pwa/favicon-96x96.png","c692f5b8705a974ebbda54d96872c190"],["images/pwa/icon.png","d9802d1525f604c28cff0a7c84c27f35"],["images/pwa/mstile-150x150.png","53350332972028060ac2bb4b132a1dcb"],["images/pwa/mstile-310x150.png","3eceb46bdb20d956526ef0f8882740e1"],["images/pwa/mstile-70x70.png","0357685c2f72338d7ef994f483f89548"],["images/pwa/safari-pinned-tab.svg","fc93b99a24fc46df30fca909e6fd903a"],["images/urish.png","8f46ed72c8e0585d96c152d14ac383a0"],["images/wassim.png","25331e697b07d536248f4580ce0e468b"],["index.html","24a7085db8e6625458c8b7d5de2adcc6"],["manifest.json","4a961ec9052d8cbd8ea13937e9660963"],["responsivevoice.js","f39bdd7aaccb3a8128122a069ba8c580"]]; 41 | var cacheName = 'sw-precache-v2-let-me-see-v1-' + (self.registration ? self.registration.scope : ''); 42 | 43 | 44 | var ignoreUrlParametersMatching = [/./]; 45 | 46 | 47 | 48 | var addDirectoryIndex = function (originalUrl, index) { 49 | var url = new URL(originalUrl); 50 | if (url.pathname.slice(-1) === '/') { 51 | url.pathname += index; 52 | } 53 | return url.toString(); 54 | }; 55 | 56 | var createCacheKey = function (originalUrl, paramName, paramValue, 57 | dontCacheBustUrlsMatching) { 58 | // Create a new URL object to avoid modifying originalUrl. 59 | var url = new URL(originalUrl); 60 | 61 | // If dontCacheBustUrlsMatching is not set, or if we don't have a match, 62 | // then add in the extra cache-busting URL parameter. 63 | if (!dontCacheBustUrlsMatching || 64 | !(url.toString().match(dontCacheBustUrlsMatching))) { 65 | url.search += (url.search ? '&' : '') + 66 | encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue); 67 | } 68 | 69 | return url.toString(); 70 | }; 71 | 72 | var isPathWhitelisted = function (whitelist, absoluteUrlString) { 73 | // If the whitelist is empty, then consider all URLs to be whitelisted. 74 | if (whitelist.length === 0) { 75 | return true; 76 | } 77 | 78 | // Otherwise compare each path regex to the path of the URL passed in. 79 | var path = (new URL(absoluteUrlString)).pathname; 80 | return whitelist.some(function(whitelistedPathRegex) { 81 | return path.match(whitelistedPathRegex); 82 | }); 83 | }; 84 | 85 | var stripIgnoredUrlParameters = function (originalUrl, 86 | ignoreUrlParametersMatching) { 87 | var url = new URL(originalUrl); 88 | 89 | url.search = url.search.slice(1) // Exclude initial '?' 90 | .split('&') // Split into an array of 'key=value' strings 91 | .map(function(kv) { 92 | return kv.split('='); // Split each 'key=value' string into a [key, value] array 93 | }) 94 | .filter(function(kv) { 95 | return ignoreUrlParametersMatching.every(function(ignoredRegex) { 96 | return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes. 97 | }); 98 | }) 99 | .map(function(kv) { 100 | return kv.join('='); // Join each [key, value] array into a 'key=value' string 101 | }) 102 | .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each 103 | 104 | return url.toString(); 105 | }; 106 | 107 | 108 | var hashParamName = '_sw-precache'; 109 | var urlsToCacheKeys = new Map( 110 | precacheConfig.map(function(item) { 111 | var relativeUrl = item[0]; 112 | var hash = item[1]; 113 | var absoluteUrl = new URL(relativeUrl, self.location); 114 | var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false); 115 | return [absoluteUrl.toString(), cacheKey]; 116 | }) 117 | ); 118 | 119 | function setOfCachedUrls(cache) { 120 | return cache.keys().then(function(requests) { 121 | return requests.map(function(request) { 122 | return request.url; 123 | }); 124 | }).then(function(urls) { 125 | return new Set(urls); 126 | }); 127 | } 128 | 129 | self.addEventListener('install', function(event) { 130 | event.waitUntil( 131 | caches.open(cacheName).then(function(cache) { 132 | return setOfCachedUrls(cache).then(function(cachedUrls) { 133 | return Promise.all( 134 | Array.from(urlsToCacheKeys.values()).map(function(cacheKey) { 135 | // If we don't have a key matching url in the cache already, add it. 136 | if (!cachedUrls.has(cacheKey)) { 137 | return cache.add(new Request(cacheKey, {credentials: 'same-origin'})); 138 | } 139 | }) 140 | ); 141 | }); 142 | }).then(function() { 143 | 144 | // Force the SW to transition from installing -> active state 145 | return self.skipWaiting(); 146 | 147 | }) 148 | ); 149 | }); 150 | 151 | self.addEventListener('activate', function(event) { 152 | var setOfExpectedUrls = new Set(urlsToCacheKeys.values()); 153 | 154 | event.waitUntil( 155 | caches.open(cacheName).then(function(cache) { 156 | return cache.keys().then(function(existingRequests) { 157 | return Promise.all( 158 | existingRequests.map(function(existingRequest) { 159 | if (!setOfExpectedUrls.has(existingRequest.url)) { 160 | return cache.delete(existingRequest); 161 | } 162 | }) 163 | ); 164 | }); 165 | }).then(function() { 166 | 167 | return self.clients.claim(); 168 | 169 | }) 170 | ); 171 | }); 172 | 173 | 174 | self.addEventListener('fetch', function(event) { 175 | if (event.request.method === 'GET') { 176 | // Should we call event.respondWith() inside this fetch event handler? 177 | // This needs to be determined synchronously, which will give other fetch 178 | // handlers a chance to handle the request if need be. 179 | var shouldRespond; 180 | 181 | // First, remove all the ignored parameter and see if we have that URL 182 | // in our cache. If so, great! shouldRespond will be true. 183 | var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching); 184 | shouldRespond = urlsToCacheKeys.has(url); 185 | 186 | // If shouldRespond is false, check again, this time with 'index.html' 187 | // (or whatever the directoryIndex option is set to) at the end. 188 | var directoryIndex = 'index.html'; 189 | if (!shouldRespond && directoryIndex) { 190 | url = addDirectoryIndex(url, directoryIndex); 191 | shouldRespond = urlsToCacheKeys.has(url); 192 | } 193 | 194 | // If shouldRespond is still false, check to see if this is a navigation 195 | // request, and if so, whether the URL matches navigateFallbackWhitelist. 196 | var navigateFallback = ''; 197 | if (!shouldRespond && 198 | navigateFallback && 199 | (event.request.mode === 'navigate') && 200 | isPathWhitelisted([], event.request.url)) { 201 | url = new URL(navigateFallback, self.location).toString(); 202 | shouldRespond = urlsToCacheKeys.has(url); 203 | } 204 | 205 | // If shouldRespond was set to true at any point, then call 206 | // event.respondWith(), using the appropriate cache key. 207 | if (shouldRespond) { 208 | event.respondWith( 209 | caches.open(cacheName).then(function(cache) { 210 | return cache.match(urlsToCacheKeys.get(url)).then(function(response) { 211 | if (response) { 212 | return response; 213 | } 214 | throw Error('The cached response that was expected is missing.'); 215 | }); 216 | }).catch(function(e) { 217 | // Fall back to just fetch()ing the request if some unexpected error 218 | // prevented the cached response from being valid. 219 | console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e); 220 | return fetch(event.request); 221 | }) 222 | ); 223 | } 224 | } 225 | }); 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | --------------------------------------------------------------------------------