├── src ├── assets │ └── .gitkeep ├── app │ ├── app.component.css │ ├── app.component.html │ ├── app.module.ts │ ├── app.component.spec.ts │ └── app.component.ts ├── favicon.ico ├── styles.css ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── main.ts ├── index.html ├── test.ts └── polyfills.ts ├── docs ├── favicon.ico ├── index.html ├── runtime-es5.js.map ├── runtime-es2015.js.map ├── runtime-es5.js ├── runtime-es2015.js ├── styles-es2015.js.map ├── styles-es2015.js ├── styles-es5.js ├── styles-es5.js.map └── main-es2015.js.map ├── projects └── angular-rave │ ├── tsconfig.lib.prod.json │ ├── src │ ├── lib │ │ ├── angular-rave-token.ts │ │ ├── private-rave-options.ts │ │ ├── angular-rave.module.ts │ │ ├── angular-rave.service.spec.ts │ │ ├── angular-rave.directive.spec.ts │ │ ├── angular-rave.directive.ts │ │ ├── angular-rave.component.ts │ │ ├── angular-rave.service.ts │ │ ├── rave-options.ts │ │ └── angular-rave.component.spec.ts │ ├── public-api.ts │ └── test.ts │ ├── ng-package.json │ ├── tsconfig.spec.json │ ├── tslint.json │ ├── tsconfig.lib.json │ ├── package.json │ ├── LICENSE.md │ ├── karma.conf.js │ ├── CHANGELOG.md │ └── README.md ├── e2e ├── src │ ├── app.po.ts │ └── app.e2e-spec.ts ├── tsconfig.e2e.json ├── tsconfig.json └── protractor.conf.js ├── tsconfig.app.json ├── .editorconfig ├── tsconfig.spec.json ├── .all-contributorsrc ├── .browserslistrc ├── .travis.yml ├── scripts └── copy-artifacts.js ├── .github └── workflows │ └── nodejs.yml ├── tsconfig.json ├── .gitignore ├── LICENSE.md ├── CHANGELOG.md ├── package.json ├── tslint.json ├── angular.json └── README.md /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashinzekene/angular-rave/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashinzekene/angular-rave/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /projects/angular-rave/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave-token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionToken } from '@angular/core'; 2 | 3 | export const PUBKEY_TOKEN = new InjectionToken('Rave.PubKey'); 4 | -------------------------------------------------------------------------------- /projects/angular-rave/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/angular-rave", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/app", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts", 9 | "src/polyfills.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /projects/angular-rave/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /projects/angular-rave/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/angular-rave/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of angular-rave 3 | */ 4 | 5 | export * from './lib/angular-rave.service'; 6 | export * from './lib/angular-rave.component'; 7 | export * from './lib/angular-rave.directive'; 8 | export * from './lib/rave-options'; 9 | export * from './lib/angular-rave.module'; 10 | export { RaveCallback, RavePaymentData } from './lib/private-rave-options'; 11 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": ["README.md"], 3 | "imageSize": 100, 4 | "contributorsPerLine": 7, 5 | "badgeTemplate": "[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg?style=flat-square)](#contributors)", 6 | "contributorTemplate": "<%= avatarBlock %>
<%= contributions %>", 7 | }, 8 | "skipCi": "true", 9 | "contributors": [] 10 | } 11 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: xenial 2 | os: linux 3 | 4 | addons: 5 | apt: 6 | sources: 7 | - google-chrome 8 | packages: 9 | - google-chrome-stable 10 | 11 | language: node_js 12 | node_js: 13 | - "12" 14 | 15 | cache: 16 | directories: 17 | - ./node_modules 18 | 19 | install: 20 | - npm ci 21 | 22 | script: 23 | - npx ng lint 24 | - npm run-script build 25 | - npm t 26 | - npx ng test angular-rave -- --no-watch --no-progress --browsers=ChromeHeadlessCI 27 | 28 | notifications: 29 | email: false -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AppComponent } from './app.component'; 5 | import { AngularRaveModule } from 'angular-rave'; 6 | 7 | @NgModule({ 8 | imports: [ 9 | BrowserModule, 10 | AngularRaveModule.forRoot( 11 | 'FLWPUBK_TEST-ccf7c01dd5d4e69db74608b8c3a09499-X' 12 | ), 13 | ], 14 | declarations: [ 15 | AppComponent, 16 | ], 17 | providers: [], 18 | bootstrap: [AppComponent] 19 | }) 20 | export class AppModule { } 21 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/private-rave-options.ts: -------------------------------------------------------------------------------- 1 | import { RaveOptions, RaveCustomer } from './rave-options'; 2 | 3 | export interface RavePaymentData { 4 | amount: number; 5 | currency: string; 6 | customer: RaveCustomer; 7 | flw_ref: string; 8 | status: string; 9 | tx_ref: string; 10 | transaction_id: string; 11 | } 12 | 13 | export interface PrivateRaveOptions extends RaveOptions { 14 | payment_options: string; 15 | callback: RaveCallback; 16 | onclose: () => void; 17 | } 18 | 19 | export type RaveCallback = (paymentData: RavePaymentData) => void; 20 | -------------------------------------------------------------------------------- /projects/angular-rave/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true, 8 | "types": [], 9 | "lib": [ 10 | "dom", 11 | "es2018" 12 | ] 13 | }, 14 | "angularCompilerOptions": { 15 | "skipTemplateCodegen": true, 16 | "strictMetadataEmit": true, 17 | "fullTemplateTypeCheck": true, 18 | "strictInjectionParameters": true, 19 | "enableResourceInlining": true 20 | }, 21 | "exclude": [ 22 | "src/test.ts", 23 | "**/*.spec.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /scripts/copy-artifacts.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs") 2 | const path = require("path") 3 | 4 | const artifacts = ["README.md", "CHANGELOG.md", "LICENSE.md"] 5 | artifacts.forEach(file => { 6 | let fromPath = path.resolve(__dirname, '..', file) 7 | let destPath = path.resolve(__dirname, '..', 'projects/angular-rave/', file) 8 | fs.readFile(fromPath, "utf-8", (err, data) => { 9 | if (err) { 10 | console.log("An error occured:", err) 11 | return 12 | } 13 | fs.writeFile(destPath, data, (err) => { 14 | if (err) { 15 | console.log("An error occured:", err) 16 | return 17 | } 18 | console.log(`Copied ${file}:`) 19 | }) 20 | }) 21 | }) -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: npm install, lint, build, and test 21 | run: | 22 | npm ci 23 | npx ng lint 24 | npx ng build 25 | npm t 26 | npx ng test angular-rave -- --no-watch --no-progress --browsers=ChromeHeadlessCI 27 | env: 28 | CI: true 29 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * In development mode, to ignore zone related error stack frames such as 11 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 12 | * import the following file, but please comment it out in production mode 13 | * because it will have performance impact when throw error 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularRave 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Loading... 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "es2020", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ], 22 | "paths": { 23 | "angular-rave": [ 24 | "dist/angular-rave" 25 | ], 26 | "angular-rave/*": [ 27 | "dist/angular-rave/*" 28 | ] 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "typeRoots": [ 16 | "node_modules/@types" 17 | ], 18 | "lib": [ 19 | "es2018", 20 | "dom" 21 | ], 22 | "paths": { 23 | "angular-rave": [ 24 | "dist/angular-rave" 25 | ], 26 | "angular-rave/*": [ 27 | "dist/angular-rave/*" 28 | ] 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /tmp 5 | /out-tsc 6 | /uploads 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | /lib 28 | 29 | # misc 30 | /.sass-cache 31 | /connect.lock 32 | /coverage 33 | /libpeerconnection.log 34 | npm-debug.log 35 | testem.log 36 | /typings 37 | yarn-error.log 38 | 39 | # e2e 40 | /e2e/*.js 41 | /e2e/*.map 42 | /dist 43 | # System Files 44 | .DS_Store 45 | Thumbs.db 46 | yarn.lock 47 | -------------------------------------------------------------------------------- /projects/angular-rave/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone'; 4 | import 'zone.js/dist/zone-testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | declare const require: any; 12 | 13 | // First, initialize the Angular testing environment. 14 | getTestBed().initTestEnvironment( 15 | BrowserDynamicTestingModule, 16 | platformBrowserDynamicTesting() 17 | ); 18 | // Then we find all the tests. 19 | const context = require.context('./', true, /\.spec\.ts$/); 20 | // And load the modules. 21 | context.keys().map(context); 22 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, waitForAsync } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(waitForAsync(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'angular-rave-lib'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('angular-rave-lib'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './src/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /projects/angular-rave/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-rave", 3 | "version": "3.0.0", 4 | "peerDependencies": { 5 | "@angular/common": "^8.0.3", 6 | "@angular/core": "^8.0.3" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/ashinzekene/angular-rave.git" 11 | }, 12 | "license": "MIT", 13 | "author": { 14 | "email": "ashinzekene@gmail.com", 15 | "name": "Ashinze Ekene", 16 | "url": "https://github.com/ashinzekene" 17 | }, 18 | "bugs": { 19 | "email": "ashinzekene@gmail.com", 20 | "url": "https://github.com/ashinzekene/angular-rave/issues" 21 | }, 22 | "description": "Angular wrapper for integrating rave transactions", 23 | "dependencies": { 24 | "tslib": "^2.0.0" 25 | }, 26 | "keywords": [ 27 | "angular", 28 | "payment", 29 | "ravepayment", 30 | "flutterwave", 31 | "gateway" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { AngularRaveComponent } from './angular-rave.component'; 5 | import { AngularRaveDirective } from './angular-rave.directive'; 6 | import { AngularRaveService } from './angular-rave.service'; 7 | import { PUBKEY_TOKEN } from './angular-rave-token'; 8 | 9 | @NgModule({ 10 | imports: [CommonModule], 11 | declarations: [AngularRaveDirective, AngularRaveComponent], 12 | exports: [AngularRaveDirective, AngularRaveComponent], 13 | }) 14 | export class AngularRaveModule { 15 | static forRoot(publicKey: string): ModuleWithProviders { 16 | return { 17 | ngModule: AngularRaveModule, 18 | providers: [ 19 | AngularRaveService, 20 | { provide: PUBKEY_TOKEN, useValue: publicKey }, 21 | ] 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RaveOptions, RavePaymentData } from 'angular-rave'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.css'] 8 | }) 9 | export class AppComponent { 10 | title = 'angular-rave-lib'; 11 | raveOptions: RaveOptions = { 12 | amount: 3000, 13 | customer: { 14 | email: 'user@ravemail.com', 15 | phonenumber: '09010910901', 16 | name: 'Ekene Ashinze', 17 | }, 18 | customizations: { 19 | description: 'This is a flutterwave modal implemented using angular rave', 20 | title: 'Angular Rave', 21 | logo: 'https://angular.io/assets/images/logos/angular/angular.svg', 22 | }, 23 | tx_ref: `${Math.random() * 1000000}`, 24 | }; 25 | 26 | paymentFailure() { 27 | console.log('Payment Failed'); 28 | } 29 | 30 | paymentSuccess(res: RavePaymentData) { 31 | console.log('Payment complete', res); 32 | } 33 | 34 | paymentInit() { 35 | console.log('Payment about to begin'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Ashinze Ekene 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. -------------------------------------------------------------------------------- /projects/angular-rave/LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Ashinze Ekene 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. -------------------------------------------------------------------------------- /projects/angular-rave/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/angular-rave'), 20 | reports: ['html', 'lcovonly'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true, 31 | customLaunchers: { 32 | ChromeHeadlessCI: { 33 | base: 'ChromeHeadless', 34 | flags: ['--no-sandbox'] 35 | } 36 | }, 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularRave 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Loading... 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `angular-rave` will be documented here 4 | 5 | ## 3.0.0 - 2020-09-14 6 | ### Changes 7 | - `forRoot` configuration no longer accepts an object. Now accepts only the public key 8 | - `PUBKey` now `public_key` 9 | - Implemented updated `flutterwave's` inline script. 10 | 11 | ### Removed 12 | - `autoClose` option 13 | 14 | ### Fixed 15 | - Reload on successful transaction 16 | - Callback not being called after a successful transaction 17 | 18 | ## 2.0.0 - 2019-10-19 19 | ### Added 20 | - Module `forRoot` configuration 21 | - Added the `raveOptions` input 22 | - Intelliscence support for rave options 23 | - `autoClose` modal 24 | 25 | ## 1.2.1 - 2019-01-03 26 | - close rave modal automatically after successful payment 27 | 28 | ## 1.2.0 - 2018-12-12 29 | - added (init) event to be called when payment is about to begin 30 | - rave's script is not loaded automatically 31 | 32 | ## 1.0.2 - 2018-04-17 33 | - fixed bug where txref is not passed to rave 34 | 35 | ## 1.0.1 - 2018-02-26 36 | - small bug fixes 37 | 38 | ## 0.2.1 - 2018-02-24 39 | - Changed rave script in example and on readme 40 | 41 | ## 0.2.1 - 2018-02-24 42 | - Changed ts error on readme 43 | 44 | ## 0.2.0 - 2018-02-24 45 | - Added angular rave directive 46 | - Added reaveOptions input 47 | 48 | ## 0.1.1 - 2017-09-20 49 | - Fixed minor 50 | 51 | ## 0.1.0 - 2017-09-17 52 | - Initial release 53 | -------------------------------------------------------------------------------- /projects/angular-rave/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `angular-rave` will be documented here 4 | 5 | ## 3.0.0 - 2020-09-14 6 | ### Changes 7 | - `forRoot` configuration no longer accepts an object. Now accepts only the public key 8 | - `PUBKey` now `public_key` 9 | - Implemented updated `flutterwave's` inline script. 10 | 11 | ### Removed 12 | - `autoClose` option 13 | 14 | ### Fixed 15 | - Reload on successful transaction 16 | - Callback not being called after a successful transaction 17 | 18 | ## 2.0.0 - 2019-10-19 19 | ### Added 20 | - Module `forRoot` configuration 21 | - Added the `raveOptions` input 22 | - Intelliscence support for rave options 23 | - `autoClose` modal 24 | 25 | ## 1.2.1 - 2019-01-03 26 | - close rave modal automatically after successful payment 27 | 28 | ## 1.2.0 - 2018-12-12 29 | - added (init) event to be called when payment is about to begin 30 | - rave's script is not loaded automatically 31 | 32 | ## 1.0.2 - 2018-04-17 33 | - fixed bug where txref is not passed to rave 34 | 35 | ## 1.0.1 - 2018-02-26 36 | - small bug fixes 37 | 38 | ## 0.2.1 - 2018-02-24 39 | - Changed rave script in example and on readme 40 | 41 | ## 0.2.1 - 2018-02-24 42 | - Changed ts error on readme 43 | 44 | ## 0.2.0 - 2018-02-24 45 | - Added angular rave directive 46 | - Added reaveOptions input 47 | 48 | ## 0.1.1 - 2017-09-20 49 | - Fixed minor 50 | 51 | ## 0.1.0 - 2017-09-17 52 | - Initial release 53 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { AngularRaveService } from './angular-rave.service'; 4 | import { PUBKEY_TOKEN } from './angular-rave-token'; 5 | import { PrivateRaveOptions } from './private-rave-options'; 6 | 7 | interface MyWindow extends Window { 8 | FlutterwaveCheckout: (raveOptions: Partial) => void; 9 | } 10 | declare var window: MyWindow; 11 | 12 | describe('AngularRaveService', () => { 13 | beforeEach(() => { 14 | window.FlutterwaveCheckout = undefined; 15 | 16 | TestBed.configureTestingModule({ 17 | providers: [ 18 | AngularRaveService, 19 | { provide: PUBKEY_TOKEN, useValue: 'PBFPubKey' }, 20 | ] 21 | }); 22 | }); 23 | 24 | it('should be created', inject([AngularRaveService], (service: AngularRaveService) => { 25 | expect(service).toBeTruthy(); 26 | })); 27 | 28 | it('should inject tokens', inject([AngularRaveService], (service: AngularRaveService) => { 29 | expect(service.publicKey).toEqual('PBFPubKey'); 30 | })); 31 | 32 | it('should load the flutterwave script', inject([AngularRaveService], (service: AngularRaveService) => { 33 | expect(typeof window.FlutterwaveCheckout).toEqual('undefined'); 34 | service.loadScript().then(() => { 35 | expect(typeof window.FlutterwaveCheckout).toEqual('function'); 36 | }); 37 | })); 38 | }); 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-rave-lib", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "prebuild": "node scripts/copy-artifacts.js", 8 | "build": "ng build --prod", 9 | "test:watch": "ng test angular-rave", 10 | "test": "ng test angular-rave --watch=false --browsers=ChromeHeadless", 11 | "lint": "ng lint", 12 | "e2e": "ng e2e" 13 | }, 14 | "private": true, 15 | "dependencies": { 16 | "@angular/animations": "~10.1.0", 17 | "@angular/common": "~10.1.0", 18 | "@angular/compiler": "~10.1.0", 19 | "@angular/core": "~10.1.0", 20 | "@angular/forms": "~10.1.0", 21 | "@angular/platform-browser": "~10.1.0", 22 | "@angular/platform-browser-dynamic": "~10.1.0", 23 | "@angular/router": "~10.1.0", 24 | "rxjs": "~6.6.3", 25 | "tslib": "^2.0.0", 26 | "zone.js": "~0.10.2" 27 | }, 28 | "devDependencies": { 29 | "@angular-devkit/build-angular": "~0.1001.0", 30 | "@angular-devkit/build-ng-packagr": "~0.1001.0", 31 | "@angular/cli": "~10.1.0", 32 | "@angular/compiler-cli": "~10.1.0", 33 | "@angular/language-service": "~10.1.0", 34 | "@types/node": "^12.11.1", 35 | "@types/jasmine": "~3.3.8", 36 | "@types/jasminewd2": "~2.0.3", 37 | "codelyzer": "^5.1.2", 38 | "jasmine-core": "~3.5.0", 39 | "jasmine-spec-reporter": "~5.0.0", 40 | "karma": "~5.0.0", 41 | "karma-chrome-launcher": "~3.1.0", 42 | "karma-coverage-istanbul-reporter": "~3.0.2", 43 | "karma-jasmine": "~4.0.0", 44 | "karma-jasmine-html-reporter": "^1.5.0", 45 | "ng-packagr": "^10.1.0", 46 | "protractor": "~7.0.0", 47 | "ts-node": "~7.0.0", 48 | "tslint": "~6.1.0", 49 | "typescript": "~4.0.2" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import { Component, DebugElement } from '@angular/core'; 2 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | 5 | import { AngularRaveService } from './angular-rave.service'; 6 | import { PUBKEY_TOKEN } from './angular-rave-token'; 7 | import { AngularRaveDirective } from './angular-rave.directive'; 8 | import { RaveOptions } from './rave-options'; 9 | 10 | @Component({ 11 | template: ` 12 | 13 | ` 14 | }) 15 | class TestComponent { } 16 | 17 | describe('AngularRaveDirective', () => { 18 | let component: any; 19 | let fixture: ComponentFixture; 20 | let inputEl: DebugElement; 21 | const paymentOptions: RaveOptions = { 22 | customer: { 23 | email: 'someuser@email.com', 24 | phonenumber: '09209209309090' 25 | }, 26 | customizations: { 27 | title: 'My title' 28 | }, 29 | currency: 'NGN', 30 | amount: 8000, 31 | tx_ref: 'A unique transaction reference', 32 | paymentOptions: ['account', 'banktransfer', 'card'], 33 | }; 34 | 35 | beforeEach(waitForAsync(() => { 36 | @Component({ 37 | template: ` 38 | 44 | ` 45 | }) 46 | class SampleComponent { 47 | options = paymentOptions; 48 | paymentInit() {} 49 | } 50 | 51 | TestBed.configureTestingModule({ 52 | declarations: [ TestComponent, AngularRaveDirective, SampleComponent ], 53 | providers: [ 54 | AngularRaveService, 55 | { provide: PUBKEY_TOKEN, useValue: 'public_key' }, 56 | ] 57 | }) 58 | .compileComponents(); 59 | 60 | fixture = TestBed.createComponent(SampleComponent); 61 | component = fixture.componentInstance; 62 | inputEl = fixture.debugElement.query(By.css('button')); 63 | })); 64 | 65 | it('should create', () => { 66 | expect(component).toBeTruthy(); 67 | }); 68 | 69 | it('should show modal', () => { 70 | spyOn(component, 'paymentInit'); 71 | expect(component).toBeTruthy(); 72 | setTimeout(() => { 73 | expect(component.paymentInit).toHaveBeenCalled(); 74 | }, 2000); 75 | }); 76 | 77 | }); 78 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, Input, Output, HostListener, EventEmitter } from '@angular/core'; 2 | 3 | import { PaymentOptionsEnum, RaveCustomer, RaveCustomization, RaveOptions, RaveSubAcccount } from './rave-options'; 4 | import { AngularRaveService } from './angular-rave.service'; 5 | import { RavePaymentData, PrivateRaveOptions } from './private-rave-options'; 6 | 7 | @Directive({ 8 | selector: '[angular-rave]', //tslint:disable-line 9 | }) 10 | export class AngularRaveDirective { 11 | @Input() amount: number; 12 | @Input() public_key: string; 13 | @Input() currency: string; 14 | @Input() customer: RaveCustomer; 15 | @Input() customizations: RaveCustomization; 16 | @Input() integrity_hash: string; 17 | @Input() meta: object; 18 | @Input() paymentOptions: PaymentOptionsEnum[]; 19 | @Input() payment_plan: string; 20 | @Input() redirect_url: string; 21 | @Input() subaccounts: RaveSubAcccount[]; 22 | @Input() tx_ref: string; 23 | @Input() raveOptions: RaveOptions; 24 | @Output() onclose: EventEmitter = new EventEmitter(); 25 | @Output() callback: EventEmitter = new EventEmitter(); 26 | @Output() init: EventEmitter = new EventEmitter(); 27 | private _raveOptions: PrivateRaveOptions; 28 | 29 | constructor(private raveService: AngularRaveService) { } 30 | 31 | @HostListener('click') 32 | buttonClick() { 33 | this.pay(); 34 | } 35 | 36 | async pay() { 37 | let raveOptionsError = ''; 38 | if (this.raveOptions && Object.keys(this.raveOptions).length > 1) { 39 | raveOptionsError = this.raveService.isInvalidOptions(this.raveOptions); 40 | this.insertRaveOptions(this.raveOptions); 41 | } else { 42 | raveOptionsError = this.raveService.isInvalidOptions(this as RaveOptions); 43 | this.insertRaveOptions(this as RaveOptions); 44 | } 45 | if (!!raveOptionsError) { 46 | console.error(raveOptionsError); 47 | return; 48 | } 49 | await this.raveService.loadScript(); 50 | this.raveService.checkout(this._raveOptions); 51 | if (this.init.observers.length > 0) { 52 | this.init.emit(); 53 | } 54 | } 55 | 56 | insertRaveOptions(object: Partial) { 57 | const onclose = () => { 58 | if (this.onclose.observers.length) { 59 | this.onclose.emit(); 60 | } 61 | }; 62 | 63 | const callback = (res: RavePaymentData) => { 64 | this.callback.emit(res); 65 | }; 66 | 67 | this._raveOptions = this.raveService.createRaveOptionsObject(object, callback, onclose); 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core'; 2 | 3 | import { PaymentOptionsEnum, RaveCustomer, RaveCustomization, RaveOptions, RaveSubAcccount } from './rave-options'; 4 | import { AngularRaveService } from './angular-rave.service'; 5 | import { PrivateRaveOptions, RavePaymentData } from './private-rave-options'; 6 | 7 | @Component({ 8 | selector: 'angular-rave', // tslint:disable-line 9 | template: `` 10 | }) 11 | 12 | export class AngularRaveComponent implements OnInit { 13 | @Input() amount: number; 14 | @Input() public_key: string; 15 | @Input() currency: string; 16 | @Input() customer: RaveCustomer; 17 | @Input() customizations: RaveCustomization; 18 | @Input() integrity_hash: string; 19 | @Input() meta: object; 20 | @Input() paymentOptions: PaymentOptionsEnum[]; 21 | @Input() payment_plan: string; 22 | @Input() redirect_url: string; 23 | @Input() subaccounts: RaveSubAcccount[]; 24 | @Input() tx_ref: string; 25 | @Input() raveOptions: RaveOptions; 26 | @Output() onclose: EventEmitter = new EventEmitter(); 27 | @Output() callback: EventEmitter = new EventEmitter(); 28 | @Output() init: EventEmitter = new EventEmitter(); 29 | private _raveOptions: PrivateRaveOptions; 30 | 31 | constructor(private raveService: AngularRaveService) { } 32 | 33 | async pay() { 34 | let raveOptionsError = ''; 35 | if (this.raveOptions && Object.keys(this.raveOptions).length > 1) { 36 | raveOptionsError = this.raveService.isInvalidOptions(this.raveOptions); 37 | this.insertRaveOptions(this.raveOptions); 38 | } else { 39 | raveOptionsError = this.raveService.isInvalidOptions(this as RaveOptions); 40 | this.insertRaveOptions(this as RaveOptions); 41 | } 42 | if (!!raveOptionsError) { 43 | console.error(raveOptionsError); 44 | return raveOptionsError; 45 | } 46 | await this.raveService.loadScript(); 47 | this.raveService.checkout(this._raveOptions); 48 | if (this.init.observers.length > 0) { 49 | this.init.emit(); 50 | } 51 | } 52 | 53 | insertRaveOptions(object: Partial) { 54 | const onclose = () => { 55 | if (this.onclose.observers.length) { 56 | this.onclose.emit(); 57 | } 58 | }; 59 | 60 | const callback = (res: RavePaymentData) => { 61 | this.callback.emit(res); 62 | }; 63 | 64 | this._raveOptions = this.raveService.createRaveOptionsObject(object, callback, onclose); 65 | } 66 | 67 | ngOnInit() { 68 | this.pay(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags.ts'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Inject } from '@angular/core'; 2 | import { RaveOptions } from './rave-options'; 3 | import { PUBKEY_TOKEN } from './angular-rave-token'; 4 | import { PrivateRaveOptions, RaveCallback } from './private-rave-options'; 5 | 6 | interface MyWindow extends Window { 7 | FlutterwaveCheckout: (raveOptions: Partial) => void; 8 | } 9 | declare var window: MyWindow; 10 | 11 | const CHECKOUT_SCRIPT_URL = 'https://checkout.flutterwave.com/v3.js'; 12 | 13 | @Injectable({ 14 | providedIn: 'root', 15 | }) 16 | export class AngularRaveService { 17 | 18 | constructor( 19 | @Inject(PUBKEY_TOKEN) public publicKey: string, 20 | ) { } 21 | 22 | createRaveOptionsObject(obj: Partial, callback: RaveCallback, onclose: () => void): PrivateRaveOptions { 23 | const raveOptions: Partial = {}; 24 | raveOptions.amount = obj.amount; 25 | raveOptions.public_key = obj.public_key || this.publicKey; 26 | raveOptions.currency = obj.currency || 'NGN'; 27 | if (obj.customer) { raveOptions.customer = obj.customer; } 28 | if (obj.customizations) { raveOptions.customizations = obj.customizations; } 29 | if (obj.integrity_hash) { raveOptions.integrity_hash = obj.integrity_hash; } 30 | if (obj.meta) { raveOptions.meta = obj.meta; } 31 | if (obj.paymentOptions && obj.paymentOptions.length) { raveOptions.payment_options = obj.paymentOptions.join(', '); } 32 | if (obj.payment_plan) { raveOptions.payment_plan = obj.payment_plan; } 33 | if (obj.redirect_url) { raveOptions.redirect_url = obj.redirect_url; } 34 | if (obj.subaccounts) { raveOptions.subaccounts = obj.subaccounts; } 35 | if (obj.tx_ref) { raveOptions.tx_ref = obj.tx_ref; } 36 | raveOptions.callback = callback; 37 | raveOptions.onclose = onclose; 38 | return raveOptions as PrivateRaveOptions; 39 | } 40 | 41 | loadScript(): Promise { 42 | return new Promise(resolve => { 43 | if (typeof window.FlutterwaveCheckout === 'function') { 44 | resolve(); 45 | return; 46 | } 47 | const script = window.document.createElement('script'); 48 | window.document.head.appendChild(script); 49 | const onLoadFunc = () => { 50 | script.removeEventListener('load', onLoadFunc); 51 | resolve(); 52 | }; 53 | script.addEventListener('load', onLoadFunc); 54 | const url = CHECKOUT_SCRIPT_URL; 55 | script.setAttribute('src', url); 56 | }); 57 | } 58 | 59 | isInvalidOptions(obj: Partial): string { 60 | console.log('Transaction Reference', obj.tx_ref); 61 | if (!obj.public_key && !this.publicKey) { 62 | return 'ANGULAR-RAVE: Merchant public key is required'; 63 | } 64 | if (!obj.tx_ref) { 65 | return 'ANGULAR-RAVE: A unique transaction reference is required'; 66 | } 67 | if (!obj.amount) { 68 | return 'ANGULAR-RAVE: Amount to charge is required'; 69 | } 70 | if (!obj.customer.email || !obj.customer.phonenumber) { 71 | return 'ANGULAR-RAVE: Customer email or phone number is required'; 72 | } 73 | return ''; 74 | } 75 | 76 | checkout(options: PrivateRaveOptions) { 77 | return window.FlutterwaveCheckout(options); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/rave-options.ts: -------------------------------------------------------------------------------- 1 | export interface RaveOptions { 2 | /** 3 | * Merchant public key 4 | */ 5 | public_key?: string; 6 | 7 | /** 8 | * Your transaction reference. This MUST be unique for every transaction 9 | */ 10 | tx_ref: string; 11 | 12 | /** 13 | * Amount to charge the customer. 14 | */ 15 | amount: number; 16 | 17 | /** 18 | * currency to charge in. Defaults to 'NGN' 19 | */ 20 | currency?: string; 21 | 22 | /** 23 | * This is a sha256 hash of your FlutterwaveCheckout values, it is used for passing secured values to the payment gateway. 24 | */ 25 | integrity_hash?: string; 26 | 27 | /** 28 | * This specifies the payment options to be displayed e.g - card, mobilemoney, ussd and so on. 29 | */ 30 | paymentOptions?: PaymentOptionsEnum[]; 31 | 32 | /** 33 | * This is the payment plan ID used for Recurring billing 34 | */ 35 | payment_plan?: string; 36 | 37 | /** 38 | * URL to redirect to when a transaction is completed. 39 | * This is useful for 3DSecure payments so we can redirect your customer back to a custom page you want to show them. 40 | */ 41 | redirect_url?: string; 42 | 43 | /** 44 | * This is an object that can contains your customer details: e.g - 'customer': 45 | * ```json 46 | * { 47 | * 'email': 'example@example.com', 48 | * 'phonenumber': '08012345678', 49 | * 'name': 'Takeshi Kovacs' 50 | * } 51 | * ``` 52 | */ 53 | customer: RaveCustomer; 54 | 55 | /** 56 | * This is an array of objects containing the subaccount IDs to split the payment into. Check our Split Payment page for more info 57 | */ 58 | subaccounts?: RaveSubAcccount[]; 59 | 60 | /** 61 | * This is an object that helps you include additional payment information to your request 62 | * E.g: 63 | * ```json 64 | * { 65 | * 'consumer_id': 23, 66 | * 'consumer_mac': '92a3-912ba-1192a' 67 | * } 68 | * ``` 69 | */ 70 | meta?: { [key: string]: any }; 71 | 72 | /** 73 | * This is an object that contains title, logo, and description you want to display on the modal e.g 74 | * ```json 75 | * { 76 | * 'title': 'Pied Piper Payments', 77 | * 'description': 'Middleout isn't free. Pay the price', 78 | * 'logo': 'https://assets.piedpiper.com/logo.png' 79 | * } 80 | * ``` 81 | */ 82 | customizations: RaveCustomization; 83 | } 84 | 85 | export type PaymentOptionsEnum = 86 | 'account' | 87 | 'card' | 88 | 'banktransfer' | 89 | 'mpesa' | 90 | 'mobilemoneyrwanda' | 91 | 'mobilemoneyzambia' | 92 | 'qr' | 93 | 'mobilemoneyuganda' | 94 | 'ussd' | 95 | 'credit' | 96 | 'barter' | 97 | 'mobilemoneyghana' | 98 | 'payattitude' | 99 | 'mobilemoneyfranco' | 100 | 'paga' | 101 | '1voucher' | 102 | 'mobilemoneytanzania'; 103 | 104 | export interface RaveCustomer { 105 | email: string; 106 | phonenumber: string; 107 | name?: string; 108 | } 109 | 110 | export interface RaveSubAcccount { 111 | id: string; 112 | transaction_split_ratio: number; 113 | } 114 | 115 | export interface RaveCustomization { 116 | title: string; 117 | description?: string; 118 | logo?: string; 119 | } 120 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rules": { 4 | "align": { 5 | "options": [ 6 | "parameters", 7 | "statements" 8 | ] 9 | }, 10 | "array-type": false, 11 | "arrow-parens": false, 12 | "arrow-return-shorthand": true, 13 | "deprecation": { 14 | "severity": "warn" 15 | }, 16 | "component-class-suffix": true, 17 | "contextual-lifecycle": true, 18 | "curly": true, 19 | "directive-class-suffix": true, 20 | "variable-name": { 21 | "options": [ 22 | "ban-keywords", 23 | "check-format", 24 | "allow-leading-underscore", 25 | "allow-pascal-case", 26 | "allow-snake-case" 27 | ] 28 | }, 29 | "directive-selector": [ 30 | true, 31 | "attribute", 32 | "app", 33 | "camelCase" 34 | ], 35 | "eofline": true, 36 | "component-selector": [ 37 | true, 38 | "element", 39 | "app", 40 | "kebab-case" 41 | ], 42 | "import-spacing": true, 43 | "indent": { 44 | "options": [ 45 | "spaces" 46 | ] 47 | }, 48 | "import-blacklist": [ 49 | true, 50 | "rxjs/Rx" 51 | ], 52 | "interface-name": false, 53 | "max-classes-per-file": false, 54 | "max-line-length": [ 55 | true, 56 | 140 57 | ], 58 | "member-access": false, 59 | "member-ordering": [ 60 | true, 61 | { 62 | "order": [ 63 | "static-field", 64 | "instance-field", 65 | "static-method", 66 | "instance-method" 67 | ] 68 | } 69 | ], 70 | "no-consecutive-blank-lines": false, 71 | "no-console": [ 72 | true, 73 | "debug", 74 | "info", 75 | "time", 76 | "timeEnd", 77 | "trace" 78 | ], 79 | "no-empty": false, 80 | "no-inferrable-types": [ 81 | true, 82 | "ignore-params" 83 | ], 84 | "no-non-null-assertion": true, 85 | "no-redundant-jsdoc": true, 86 | "no-switch-case-fall-through": true, 87 | "no-var-requires": false, 88 | "object-literal-key-quotes": [ 89 | true, 90 | "as-needed" 91 | ], 92 | "object-literal-sort-keys": false, 93 | "ordered-imports": false, 94 | "quotemark": [ 95 | true, 96 | "single" 97 | ], 98 | "trailing-comma": false, 99 | "no-conflicting-lifecycle": true, 100 | "no-host-metadata-property": true, 101 | "no-input-rename": true, 102 | "no-inputs-metadata-property": true, 103 | "no-output-native": true, 104 | "no-output-on-prefix": true, 105 | "semicolon": { 106 | "options": [ 107 | "always" 108 | ] 109 | }, 110 | "space-before-function-paren": { 111 | "options": { 112 | "anonymous": "never", 113 | "asyncArrow": "always", 114 | "constructor": "never", 115 | "method": "never", 116 | "named": "never" 117 | } 118 | }, 119 | "no-output-rename": true, 120 | "no-outputs-metadata-property": true, 121 | "template-banana-in-box": true, 122 | "typedef-whitespace": { 123 | "options": [ 124 | { 125 | "call-signature": "nospace", 126 | "index-signature": "nospace", 127 | "parameter": "nospace", 128 | "property-declaration": "nospace", 129 | "variable-declaration": "nospace" 130 | }, 131 | { 132 | "call-signature": "onespace", 133 | "index-signature": "onespace", 134 | "parameter": "onespace", 135 | "property-declaration": "onespace", 136 | "variable-declaration": "onespace" 137 | } 138 | ] 139 | }, 140 | "template-no-negated-async": true, 141 | "use-lifecycle-interface": true, 142 | "use-pipe-transform-interface": true, 143 | "whitespace": { 144 | "options": [ 145 | "check-branch", 146 | "check-decl", 147 | "check-operator", 148 | "check-separator", 149 | "check-type", 150 | "check-typecast" 151 | ] 152 | } 153 | }, 154 | "rulesDirectory": [ 155 | "codelyzer" 156 | ] 157 | } -------------------------------------------------------------------------------- /projects/angular-rave/src/lib/angular-rave.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; 2 | 3 | import { AngularRaveComponent } from './angular-rave.component'; 4 | import { AngularRaveService } from './angular-rave.service'; 5 | import { PUBKEY_TOKEN } from './angular-rave-token'; 6 | import { RaveOptions } from './rave-options'; 7 | 8 | describe('AngularRaveComponent', () => { 9 | let component: AngularRaveComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(waitForAsync(() => { 13 | 14 | TestBed.configureTestingModule({ 15 | declarations: [ AngularRaveComponent ], 16 | providers: [ 17 | AngularRaveService, 18 | { provide: PUBKEY_TOKEN, useValue: 'public_key' }, 19 | ] 20 | }) 21 | .compileComponents(); 22 | })); 23 | 24 | beforeEach(() => { 25 | fixture = TestBed.createComponent(AngularRaveComponent); 26 | component = fixture.componentInstance; 27 | fixture.detectChanges(); 28 | }); 29 | 30 | it('should create', () => { 31 | expect(component).toBeTruthy(); 32 | }); 33 | 34 | it('should not load the modal when the amount is not provided', async () => { 35 | spyOn(component.init, 'emit'); 36 | component.customer = { 37 | email: 'someuser@email.com', 38 | phonenumber: '09209209309090', 39 | }; 40 | component.tx_ref = 'tx-reference-val'; 41 | component.currency = 'NGN'; 42 | component.callback.subscribe(() => {}); 43 | component.init.subscribe(() => {}); 44 | const error = await component.pay(); 45 | 46 | fixture.detectChanges(); 47 | expect(error).toEqual('ANGULAR-RAVE: Amount to charge is required'); 48 | expect(component.init.emit).not.toHaveBeenCalled(); 49 | }); 50 | 51 | it('should not load the modal when the transaction reference is not provided', async () => { 52 | spyOn(component.init, 'emit'); 53 | component.customer = { 54 | email: 'someuser@email.com', 55 | phonenumber: '09209209309090', 56 | }; 57 | component.currency = 'NGN'; 58 | component.amount = 8000; 59 | component.callback.subscribe(() => {}); 60 | component.init.subscribe(() => {}); 61 | const error = await component.pay(); 62 | 63 | fixture.detectChanges(); 64 | expect(error).toEqual('ANGULAR-RAVE: A unique transaction reference is required'); 65 | expect(component.init.emit).not.toHaveBeenCalled(); 66 | }); 67 | 68 | it('should load the modal when the currency is not provided', async () => { 69 | spyOn(component.init, 'emit'); 70 | component.customer = { 71 | email: 'someuser@email.com', 72 | phonenumber: '09209209309090', 73 | }; 74 | component.paymentOptions = ['account']; 75 | component.tx_ref = 'tx-reference-val'; 76 | component.amount = 8000; 77 | component.callback.subscribe(() => {}); 78 | component.init.subscribe(() => {}); 79 | const error = await component.pay(); 80 | 81 | fixture.detectChanges(); 82 | expect(error).toBeUndefined(); 83 | expect(component.init.emit).toHaveBeenCalled(); 84 | }); 85 | 86 | it('should load the modal when the payment options is not provided', async () => { 87 | spyOn(component.init, 'emit'); 88 | component.customer = { 89 | email: 'someuser@email.com', 90 | phonenumber: '09209209309090', 91 | }; 92 | component.tx_ref = 'tx-reference-val'; 93 | component.amount = 8000; 94 | component.callback.subscribe(() => {}); 95 | component.init.subscribe(() => {}); 96 | const error = await component.pay(); 97 | 98 | fixture.detectChanges(); 99 | expect(error).toBeUndefined(); 100 | expect(component.init.emit).toHaveBeenCalled(); 101 | }); 102 | 103 | it('should load the modal when valid payment options are passed', async () => { 104 | spyOn(component.init, 'emit'); 105 | component.customer = { 106 | email: 'someuser@email.com', 107 | phonenumber: '09209209309090', 108 | }; 109 | component.currency = 'NGN'; 110 | component.amount = 8000; 111 | component.tx_ref = 'A unique transaction reference'; 112 | component.paymentOptions = ['account', 'banktransfer', 'card']; 113 | component.callback.subscribe(() => {}); 114 | component.init.subscribe(() => {}); 115 | const error = await component.pay(); 116 | 117 | fixture.detectChanges(); 118 | expect(error).toBeUndefined(); 119 | expect(component.init.emit).toHaveBeenCalled(); 120 | }); 121 | 122 | it('should load the modal when a valid payment options object is passed', async () => { 123 | spyOn(component.init, 'emit'); 124 | 125 | const paymentOptions: RaveOptions = { 126 | customer: { 127 | email: 'someuser@email.com', 128 | phonenumber: '09209209309090' 129 | }, 130 | customizations: { 131 | title: 'My title' 132 | }, 133 | currency: 'NGN', 134 | amount: 8000, 135 | tx_ref: 'A unique transaction reference', 136 | paymentOptions: ['account', 'banktransfer', 'card'], 137 | }; 138 | 139 | component.raveOptions = paymentOptions; 140 | component.callback.subscribe(() => {}); 141 | component.init.subscribe(() => {}); 142 | const error = await component.pay(); 143 | 144 | fixture.detectChanges(); 145 | expect(error).toBeUndefined(); 146 | expect(component.init.emit).toHaveBeenCalled(); 147 | }); 148 | }); 149 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "angular-rave-lib": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "docs", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "deployUrl": "angular-rave/", 20 | "polyfills": "src/polyfills.ts", 21 | "tsConfig": "tsconfig.app.json", 22 | "aot": true, 23 | "assets": [ 24 | "src/favicon.ico", 25 | "src/assets" 26 | ], 27 | "styles": [ 28 | "src/styles.css" 29 | ], 30 | "scripts": [] 31 | }, 32 | "configurations": { 33 | "production": { 34 | "fileReplacements": [ 35 | { 36 | "replace": "src/environments/environment.ts", 37 | "with": "src/environments/environment.prod.ts" 38 | } 39 | ], 40 | "optimization": true, 41 | "outputHashing": "all", 42 | "extractCss": true, 43 | "namedChunks": false, 44 | "extractLicenses": true, 45 | "vendorChunk": false, 46 | "buildOptimizer": true, 47 | "budgets": [ 48 | { 49 | "type": "initial", 50 | "maximumWarning": "2mb", 51 | "maximumError": "5mb" 52 | }, 53 | { 54 | "type": "anyComponentStyle", 55 | "maximumWarning": "6kb" 56 | } 57 | ] 58 | } 59 | } 60 | }, 61 | "serve": { 62 | "builder": "@angular-devkit/build-angular:dev-server", 63 | "options": { 64 | "browserTarget": "angular-rave-lib:build" 65 | }, 66 | "configurations": { 67 | "production": { 68 | "browserTarget": "angular-rave-lib:build:production" 69 | } 70 | } 71 | }, 72 | "extract-i18n": { 73 | "builder": "@angular-devkit/build-angular:extract-i18n", 74 | "options": { 75 | "browserTarget": "angular-rave-lib:build" 76 | } 77 | }, 78 | "test": { 79 | "builder": "@angular-devkit/build-angular:karma", 80 | "options": { 81 | "main": "src/test.ts", 82 | "polyfills": "src/polyfills.ts", 83 | "tsConfig": "tsconfig.spec.json", 84 | "karmaConfig": "karma.conf.js", 85 | "assets": [ 86 | "src/favicon.ico", 87 | "src/assets" 88 | ], 89 | "styles": [ 90 | "src/styles.css" 91 | ], 92 | "scripts": [] 93 | } 94 | }, 95 | "lint": { 96 | "builder": "@angular-devkit/build-angular:tslint", 97 | "options": { 98 | "tsConfig": [ 99 | "tsconfig.app.json", 100 | "tsconfig.spec.json", 101 | "e2e/tsconfig.json" 102 | ], 103 | "exclude": [ 104 | "**/node_modules/**" 105 | ] 106 | } 107 | }, 108 | "e2e": { 109 | "builder": "@angular-devkit/build-angular:protractor", 110 | "options": { 111 | "protractorConfig": "e2e/protractor.conf.js", 112 | "devServerTarget": "angular-rave-lib:serve" 113 | }, 114 | "configurations": { 115 | "production": { 116 | "devServerTarget": "angular-rave-lib:serve:production" 117 | } 118 | } 119 | } 120 | } 121 | }, 122 | "angular-rave": { 123 | "projectType": "library", 124 | "root": "projects/angular-rave", 125 | "sourceRoot": "projects/angular-rave/src", 126 | "prefix": "lib", 127 | "architect": { 128 | "build": { 129 | "builder": "@angular-devkit/build-ng-packagr:build", 130 | "options": { 131 | "tsConfig": "projects/angular-rave/tsconfig.lib.json", 132 | "project": "projects/angular-rave/ng-package.json" 133 | }, 134 | "configurations": { 135 | "production": { 136 | "tsConfig": "projects/angular-rave/tsconfig.lib.prod.json" 137 | } 138 | } 139 | }, 140 | "test": { 141 | "builder": "@angular-devkit/build-angular:karma", 142 | "options": { 143 | "main": "projects/angular-rave/src/test.ts", 144 | "tsConfig": "projects/angular-rave/tsconfig.spec.json", 145 | "karmaConfig": "projects/angular-rave/karma.conf.js" 146 | } 147 | }, 148 | "lint": { 149 | "builder": "@angular-devkit/build-angular:tslint", 150 | "options": { 151 | "tsConfig": [ 152 | "projects/angular-rave/tsconfig.lib.json", 153 | "projects/angular-rave/tsconfig.spec.json" 154 | ], 155 | "exclude": [ 156 | "**/node_modules/**" 157 | ] 158 | } 159 | } 160 | } 161 | } 162 | }, 163 | "defaultProject": "angular-rave", 164 | "cli": { 165 | "analytics": "52dca2ff-666c-47c5-b136-a3124d15f7b1" 166 | } 167 | } -------------------------------------------------------------------------------- /docs/runtime-es5.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack/bootstrap"],"names":[],"mappings":";QAAA;QACA;QACA;QACA;QACA;;QAEA;QACA;QACA;QACA,QAAQ,oBAAoB;QAC5B;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA,iBAAiB,4BAA4B;QAC7C;QACA;QACA,kBAAkB,2BAA2B;QAC7C;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;;QAEA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;QAEA;QACA;QACA;QACA;QACA,gBAAgB,uBAAuB;QACvC;;;QAGA;QACA","file":"runtime-es5.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"runtime\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"angular-rave/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// run deferred modules from other chunks\n \tcheckDeferredModules();\n"],"sourceRoot":"webpack:///"} -------------------------------------------------------------------------------- /docs/runtime-es2015.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack/bootstrap"],"names":[],"mappings":";QAAA;QACA;QACA;QACA;QACA;;QAEA;QACA;QACA;QACA,QAAQ,oBAAoB;QAC5B;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA,iBAAiB,4BAA4B;QAC7C;QACA;QACA,kBAAkB,2BAA2B;QAC7C;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;;QAEA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;QAEA;QACA;QACA;QACA;QACA,gBAAgB,uBAAuB;QACvC;;;QAGA;QACA","file":"runtime-es2015.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"runtime\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"angular-rave/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// run deferred modules from other chunks\n \tcheckDeferredModules();\n"],"sourceRoot":"webpack:///"} -------------------------------------------------------------------------------- /docs/runtime-es5.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // install a JSONP callback for chunk loading 3 | /******/ function webpackJsonpCallback(data) { 4 | /******/ var chunkIds = data[0]; 5 | /******/ var moreModules = data[1]; 6 | /******/ var executeModules = data[2]; 7 | /******/ 8 | /******/ // add "moreModules" to the modules object, 9 | /******/ // then flag all "chunkIds" as loaded and fire callback 10 | /******/ var moduleId, chunkId, i = 0, resolves = []; 11 | /******/ for(;i < chunkIds.length; i++) { 12 | /******/ chunkId = chunkIds[i]; 13 | /******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { 14 | /******/ resolves.push(installedChunks[chunkId][0]); 15 | /******/ } 16 | /******/ installedChunks[chunkId] = 0; 17 | /******/ } 18 | /******/ for(moduleId in moreModules) { 19 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 20 | /******/ modules[moduleId] = moreModules[moduleId]; 21 | /******/ } 22 | /******/ } 23 | /******/ if(parentJsonpFunction) parentJsonpFunction(data); 24 | /******/ 25 | /******/ while(resolves.length) { 26 | /******/ resolves.shift()(); 27 | /******/ } 28 | /******/ 29 | /******/ // add entry modules from loaded chunk to deferred list 30 | /******/ deferredModules.push.apply(deferredModules, executeModules || []); 31 | /******/ 32 | /******/ // run deferred modules when all chunks ready 33 | /******/ return checkDeferredModules(); 34 | /******/ }; 35 | /******/ function checkDeferredModules() { 36 | /******/ var result; 37 | /******/ for(var i = 0; i < deferredModules.length; i++) { 38 | /******/ var deferredModule = deferredModules[i]; 39 | /******/ var fulfilled = true; 40 | /******/ for(var j = 1; j < deferredModule.length; j++) { 41 | /******/ var depId = deferredModule[j]; 42 | /******/ if(installedChunks[depId] !== 0) fulfilled = false; 43 | /******/ } 44 | /******/ if(fulfilled) { 45 | /******/ deferredModules.splice(i--, 1); 46 | /******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); 47 | /******/ } 48 | /******/ } 49 | /******/ 50 | /******/ return result; 51 | /******/ } 52 | /******/ 53 | /******/ // The module cache 54 | /******/ var installedModules = {}; 55 | /******/ 56 | /******/ // object to store loaded and loading chunks 57 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 58 | /******/ // Promise = chunk loading, 0 = chunk loaded 59 | /******/ var installedChunks = { 60 | /******/ "runtime": 0 61 | /******/ }; 62 | /******/ 63 | /******/ var deferredModules = []; 64 | /******/ 65 | /******/ // The require function 66 | /******/ function __webpack_require__(moduleId) { 67 | /******/ 68 | /******/ // Check if module is in cache 69 | /******/ if(installedModules[moduleId]) { 70 | /******/ return installedModules[moduleId].exports; 71 | /******/ } 72 | /******/ // Create a new module (and put it into the cache) 73 | /******/ var module = installedModules[moduleId] = { 74 | /******/ i: moduleId, 75 | /******/ l: false, 76 | /******/ exports: {} 77 | /******/ }; 78 | /******/ 79 | /******/ // Execute the module function 80 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 81 | /******/ 82 | /******/ // Flag the module as loaded 83 | /******/ module.l = true; 84 | /******/ 85 | /******/ // Return the exports of the module 86 | /******/ return module.exports; 87 | /******/ } 88 | /******/ 89 | /******/ 90 | /******/ // expose the modules object (__webpack_modules__) 91 | /******/ __webpack_require__.m = modules; 92 | /******/ 93 | /******/ // expose the module cache 94 | /******/ __webpack_require__.c = installedModules; 95 | /******/ 96 | /******/ // define getter function for harmony exports 97 | /******/ __webpack_require__.d = function(exports, name, getter) { 98 | /******/ if(!__webpack_require__.o(exports, name)) { 99 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 100 | /******/ } 101 | /******/ }; 102 | /******/ 103 | /******/ // define __esModule on exports 104 | /******/ __webpack_require__.r = function(exports) { 105 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 106 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 107 | /******/ } 108 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 109 | /******/ }; 110 | /******/ 111 | /******/ // create a fake namespace object 112 | /******/ // mode & 1: value is a module id, require it 113 | /******/ // mode & 2: merge all properties of value into the ns 114 | /******/ // mode & 4: return value when already ns object 115 | /******/ // mode & 8|1: behave like require 116 | /******/ __webpack_require__.t = function(value, mode) { 117 | /******/ if(mode & 1) value = __webpack_require__(value); 118 | /******/ if(mode & 8) return value; 119 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 120 | /******/ var ns = Object.create(null); 121 | /******/ __webpack_require__.r(ns); 122 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 123 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 124 | /******/ return ns; 125 | /******/ }; 126 | /******/ 127 | /******/ // getDefaultExport function for compatibility with non-harmony modules 128 | /******/ __webpack_require__.n = function(module) { 129 | /******/ var getter = module && module.__esModule ? 130 | /******/ function getDefault() { return module['default']; } : 131 | /******/ function getModuleExports() { return module; }; 132 | /******/ __webpack_require__.d(getter, 'a', getter); 133 | /******/ return getter; 134 | /******/ }; 135 | /******/ 136 | /******/ // Object.prototype.hasOwnProperty.call 137 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 138 | /******/ 139 | /******/ // __webpack_public_path__ 140 | /******/ __webpack_require__.p = "angular-rave/"; 141 | /******/ 142 | /******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; 143 | /******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); 144 | /******/ jsonpArray.push = webpackJsonpCallback; 145 | /******/ jsonpArray = jsonpArray.slice(); 146 | /******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); 147 | /******/ var parentJsonpFunction = oldJsonpFunction; 148 | /******/ 149 | /******/ 150 | /******/ // run deferred modules from other chunks 151 | /******/ checkDeferredModules(); 152 | /******/ }) 153 | /************************************************************************/ 154 | /******/ ([]); 155 | //# sourceMappingURL=runtime-es5.js.map -------------------------------------------------------------------------------- /docs/runtime-es2015.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // install a JSONP callback for chunk loading 3 | /******/ function webpackJsonpCallback(data) { 4 | /******/ var chunkIds = data[0]; 5 | /******/ var moreModules = data[1]; 6 | /******/ var executeModules = data[2]; 7 | /******/ 8 | /******/ // add "moreModules" to the modules object, 9 | /******/ // then flag all "chunkIds" as loaded and fire callback 10 | /******/ var moduleId, chunkId, i = 0, resolves = []; 11 | /******/ for(;i < chunkIds.length; i++) { 12 | /******/ chunkId = chunkIds[i]; 13 | /******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { 14 | /******/ resolves.push(installedChunks[chunkId][0]); 15 | /******/ } 16 | /******/ installedChunks[chunkId] = 0; 17 | /******/ } 18 | /******/ for(moduleId in moreModules) { 19 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { 20 | /******/ modules[moduleId] = moreModules[moduleId]; 21 | /******/ } 22 | /******/ } 23 | /******/ if(parentJsonpFunction) parentJsonpFunction(data); 24 | /******/ 25 | /******/ while(resolves.length) { 26 | /******/ resolves.shift()(); 27 | /******/ } 28 | /******/ 29 | /******/ // add entry modules from loaded chunk to deferred list 30 | /******/ deferredModules.push.apply(deferredModules, executeModules || []); 31 | /******/ 32 | /******/ // run deferred modules when all chunks ready 33 | /******/ return checkDeferredModules(); 34 | /******/ }; 35 | /******/ function checkDeferredModules() { 36 | /******/ var result; 37 | /******/ for(var i = 0; i < deferredModules.length; i++) { 38 | /******/ var deferredModule = deferredModules[i]; 39 | /******/ var fulfilled = true; 40 | /******/ for(var j = 1; j < deferredModule.length; j++) { 41 | /******/ var depId = deferredModule[j]; 42 | /******/ if(installedChunks[depId] !== 0) fulfilled = false; 43 | /******/ } 44 | /******/ if(fulfilled) { 45 | /******/ deferredModules.splice(i--, 1); 46 | /******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); 47 | /******/ } 48 | /******/ } 49 | /******/ 50 | /******/ return result; 51 | /******/ } 52 | /******/ 53 | /******/ // The module cache 54 | /******/ var installedModules = {}; 55 | /******/ 56 | /******/ // object to store loaded and loading chunks 57 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 58 | /******/ // Promise = chunk loading, 0 = chunk loaded 59 | /******/ var installedChunks = { 60 | /******/ "runtime": 0 61 | /******/ }; 62 | /******/ 63 | /******/ var deferredModules = []; 64 | /******/ 65 | /******/ // The require function 66 | /******/ function __webpack_require__(moduleId) { 67 | /******/ 68 | /******/ // Check if module is in cache 69 | /******/ if(installedModules[moduleId]) { 70 | /******/ return installedModules[moduleId].exports; 71 | /******/ } 72 | /******/ // Create a new module (and put it into the cache) 73 | /******/ var module = installedModules[moduleId] = { 74 | /******/ i: moduleId, 75 | /******/ l: false, 76 | /******/ exports: {} 77 | /******/ }; 78 | /******/ 79 | /******/ // Execute the module function 80 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 81 | /******/ 82 | /******/ // Flag the module as loaded 83 | /******/ module.l = true; 84 | /******/ 85 | /******/ // Return the exports of the module 86 | /******/ return module.exports; 87 | /******/ } 88 | /******/ 89 | /******/ 90 | /******/ // expose the modules object (__webpack_modules__) 91 | /******/ __webpack_require__.m = modules; 92 | /******/ 93 | /******/ // expose the module cache 94 | /******/ __webpack_require__.c = installedModules; 95 | /******/ 96 | /******/ // define getter function for harmony exports 97 | /******/ __webpack_require__.d = function(exports, name, getter) { 98 | /******/ if(!__webpack_require__.o(exports, name)) { 99 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 100 | /******/ } 101 | /******/ }; 102 | /******/ 103 | /******/ // define __esModule on exports 104 | /******/ __webpack_require__.r = function(exports) { 105 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 106 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 107 | /******/ } 108 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 109 | /******/ }; 110 | /******/ 111 | /******/ // create a fake namespace object 112 | /******/ // mode & 1: value is a module id, require it 113 | /******/ // mode & 2: merge all properties of value into the ns 114 | /******/ // mode & 4: return value when already ns object 115 | /******/ // mode & 8|1: behave like require 116 | /******/ __webpack_require__.t = function(value, mode) { 117 | /******/ if(mode & 1) value = __webpack_require__(value); 118 | /******/ if(mode & 8) return value; 119 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 120 | /******/ var ns = Object.create(null); 121 | /******/ __webpack_require__.r(ns); 122 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 123 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 124 | /******/ return ns; 125 | /******/ }; 126 | /******/ 127 | /******/ // getDefaultExport function for compatibility with non-harmony modules 128 | /******/ __webpack_require__.n = function(module) { 129 | /******/ var getter = module && module.__esModule ? 130 | /******/ function getDefault() { return module['default']; } : 131 | /******/ function getModuleExports() { return module; }; 132 | /******/ __webpack_require__.d(getter, 'a', getter); 133 | /******/ return getter; 134 | /******/ }; 135 | /******/ 136 | /******/ // Object.prototype.hasOwnProperty.call 137 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 138 | /******/ 139 | /******/ // __webpack_public_path__ 140 | /******/ __webpack_require__.p = "angular-rave/"; 141 | /******/ 142 | /******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; 143 | /******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); 144 | /******/ jsonpArray.push = webpackJsonpCallback; 145 | /******/ jsonpArray = jsonpArray.slice(); 146 | /******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); 147 | /******/ var parentJsonpFunction = oldJsonpFunction; 148 | /******/ 149 | /******/ 150 | /******/ // run deferred modules from other chunks 151 | /******/ checkDeferredModules(); 152 | /******/ }) 153 | /************************************************************************/ 154 | /******/ ([]); 155 | //# sourceMappingURL=runtime-es2015.js.map -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ANGULAR-RAVE 2 | 3 | > Easily intergrate the [rave](https://ravepay.co/) payment gateway in your angular2+ project 4 | 5 | ## HOW TO USE 6 | 7 | You can checkout the demo [here](https://ashinzekene.github.io/angular-rave) 8 | 9 | ### 1. Install the module 10 | 11 | Run this in the root of your angular project 12 | ```bash 13 | npm install --save angular-rave 14 | ``` 15 | 16 | ### 2. Import the module into your project like so 17 | 18 | ```ts 19 | import { NgModule } from '@angular/core'; 20 | import { AngularRaveModule } from 'angular-rave'; 21 | ... 22 | 23 | @NgModlule({ 24 | imports: [ 25 | AngularRaveModule.forRoot('FLWPUBK-XXXXXXXXXXXXXXXXXXX'), 26 | ] 27 | }) 28 | ``` 29 | where `FLWPUBK-XXXXXXXXXXXXXXXXXXX` is your public key which can be found on the flutterwave dashboard 30 | 31 | ### 3. Implementing Angular-rave 32 | 33 | There are two option available 34 | 35 | - The `angular-rave` component: 36 | ```html 37 | 46 | ``` 47 | 48 | 2. The `angular-rave` directive: 49 | ```html 50 | 60 | ``` 61 | And then in your `component.ts` file: 62 | 63 | ```ts 64 | import { Component } from '@angular/core'; 65 | import { RavePaymentData } from 'angular-rave'; 66 | 67 | @Component({ 68 | selector: 'app-root', 69 | templateUrl: './app.component.html', 70 | styleUrls: ['./app.component.css'] 71 | }) 72 | export class AppComponent { 73 | paymentFailure() { 74 | console.log('Payment Failed'); 75 | } 76 | 77 | paymentSuccess(res: RavePaymentData) { 78 | console.log('Payment complete', res); 79 | // Verify the transaction 80 | } 81 | 82 | paymentInit() { 83 | console.log('Payment about to begin'); 84 | } 85 | } 86 | 87 | ``` 88 | 89 | ### Rave Options 90 | You can also pass in an object containing your rave options like so 91 | 92 | ```html 93 | 102 | 103 | ``` 104 | And then you can import the `RaveOptions` class for help in typing 105 | ```ts 106 | import { RaveOptions } from 'angular-rave'; 107 | 108 | ... 109 | raveOptions: RaveOptions = { 110 | amount: 3000, 111 | customer: { 112 | email: 'user@ravemail.com', 113 | phonenumber: '09010910901', 114 | name: 'Ekene Ashinze', 115 | }, 116 | customizations: { 117 | description: 'This is a flutterwave modal implemented using angular rave', 118 | title: 'Angular Rave', 119 | logo: 'https://angular.io/assets/images/logos/angular/angular.svg', 120 | }, 121 | tx_ref: `${Math.random() * 1000000}`, 122 | }; 123 | ``` 124 | And then in the template 125 | ```html 126 | 131 | ``` 132 | 133 | ### Rave Key Specificity 134 | Also, you can pass in a key in the component and the directive, in such situation, 135 | this key is given a higher preference over the global `forRoot` key. 136 | For example, if you have this is your module file 137 | 138 | ```ts 139 | @NgModule({ 140 | imports: [ 141 | AngularRaveModule.forRoot('FLWPUBK-1000'), 142 | ] 143 | }) 144 | ``` 145 | and this in your component 146 | ```html 147 | 154 | ``` 155 | Then `FLWPUBK-2000` would be used instead 156 | 157 | **NOTE:** 158 | 159 | - When using the component, the rave's payment popup shows once the component is rendered while using the directive the popup shows on click 160 | - Always generate a sensible unique reference for every transaction (unlike what I did up there 😉) 161 | - After successful payment always perform server verification 162 | 163 | ## OPTIONS 164 | 165 | | Name | Type | Required | Default Value | Description | 166 | |-------------------------|---------------------------|-------------------|:---------------:|:--------------------------------------------------| 167 | | public_key | string | true | - | Merchant public key 168 | | tx_ref | string | true | - | Your transaction reference. This MUST be unique for every transaction 169 | | amount | number | true | - | Amount to charge the customer. 170 | | currency | string | false | 'NGN' | currency to charge in. Defaults to 'NGN' 171 | | integrity_hash | string | false | - | This is a sha256 hash of your FlutterwaveCheckout values, it is used for passing secured values to the payment gateway. 172 | | paymentOptions | `PaymentOptionsEnum[]` | false | - |This specifies the payment options to be displayed e.g - card, mobilemoney, ussd and so on. 173 | | payment_plan | string | false | - | This is the payment plan ID used for Recurring billing 174 | | subaccounts | `RaveSubAcccount[]` | false | - |This is an array of objects containing the subaccount IDs to split the payment into. Check our Split Payment page for more info 175 | | redirect_url | string | false | - | URL to redirect to when a transaction is completed. This is useful for 3DSecure payments so we can redirect your customer back to a custom page you want to show them. 176 | | customer | RaveCustomer | true | - | This is an object that can contains your customer details: e.g: `{ 'email': 'example@example.com', 'phonenumber': '08012345678', 'name': 'Takeshi Kovacs'}` 177 | | meta | `{[key: string]: any}` | false | - | This is an object that helps you include additional payment information to your request `{'consumer_id': 23,'consumer_mac': '92a3-912ba-1192a'}` 178 | | customizations | `RaveCustomization` | true | - | This is an object that contains title, logo, and description you want to display on the modal e.g `{'title': 'Pied Piper Payments', 'description': 'Middleout isn't free. Pay the price', 'logo': 'https://assets.piedpiper.com/logo.png'}` 179 | | init | `() => void` | false | - | A function to be called when payment is about to begin 180 | | onclose | function() | false | - | A function to be called when the pay modal is closed before a transaction is completed. 181 | | callback | (res: RavePaymentData) => void | true | - | A function to be called on successful card charge. Users can always be redirected to a successful or failed page supplied by the merchant here based on response. 182 | 183 | > You can get more information from [rave's documentation](https://flutterwavedevelopers.readme.io/) 184 | > Type definitions can be found [here](./projects/angular-rave/src/lib/rave-options.ts) 185 | 186 | ## CONTRIBUTING 187 | 188 | Feel free to create issues and submit pull requests to make corrections or enhance functionality 189 | 190 | Two projects exist in this repository 191 | - The `Angular-rave` package: [`./projects/angular-rave`](./projects/angular-rave) 192 | - The `Angular-rave-lib` demo: [`./src`](./src) 193 | 194 | ### Angular-rave project 195 | - Found at `./projects/angular-rave/src/lib`. 196 | - The artifacts ([README.md](./projects/angular-rave/README.md), [CHANGELOG.md](./projects/angular-rave/CHANGELOG.md) and [LICENSE.md](./projects/angular-rave/LICENSE.md)) in the `./projects/angular-rave/` folder are overwritten on [build](./package.json#L7) 197 | - Running `npm run build` on the main folder builds this project by [default](./angular.json#L155) 198 | 199 | ### Demo 200 | - To serve this project run `npm start`/`ng serve`. 201 | - This project makes use of the [built package](./tsconfig.json#L23) from the `angular-rave` library for quick testing and real-life debugging. So it's **important** to initially run `npm run build`/`ng build` before serving this project 202 | - To build this project, run `npm run build angular-rave-lib`. The compiled files are built to the `docs` folder for GitHub Pages. 203 | - This project is also served on github pages at https://ashinzekene.github.io/angular-rave/ 204 | 205 | ## Release 206 | - Checkout to a new release branch `release/new-version` eg `release/3.0.0` 207 | - cd into `projects/angular-rave` 208 | - Run `npm version patch|minor|major` 209 | - cd into the main directory and run `npm build` 210 | - Run `git add . && git commit -m new-version` 211 | - Run `git tag -a new-version "release notes..."` 212 | - cd into `dist/angular-rave` and run `npm publish` 213 | 214 | Thanks! 215 | Ashinze Ekene. 216 | 217 | ## License 218 | 219 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 220 | -------------------------------------------------------------------------------- /projects/angular-rave/README.md: -------------------------------------------------------------------------------- 1 | # ANGULAR-RAVE 2 | 3 | > Easily intergrate the [rave](https://ravepay.co/) payment gateway in your angular2+ project 4 | 5 | ## HOW TO USE 6 | 7 | You can checkout the demo [here](https://ashinzekene.github.io/angular-rave) 8 | 9 | ### 1. Install the module 10 | 11 | Run this in the root of your angular project 12 | ```bash 13 | npm install --save angular-rave 14 | ``` 15 | 16 | ### 2. Import the module into your project like so 17 | 18 | ```ts 19 | import { NgModule } from '@angular/core'; 20 | import { AngularRaveModule } from 'angular-rave'; 21 | ... 22 | 23 | @NgModlule({ 24 | imports: [ 25 | AngularRaveModule.forRoot('FLWPUBK-XXXXXXXXXXXXXXXXXXX'), 26 | ] 27 | }) 28 | ``` 29 | where `FLWPUBK-XXXXXXXXXXXXXXXXXXX` is your public key which can be found on the flutterwave dashboard 30 | 31 | ### 3. Implementing Angular-rave 32 | 33 | There are two option available 34 | 35 | - The `angular-rave` component: 36 | ```html 37 | 46 | ``` 47 | 48 | 2. The `angular-rave` directive: 49 | ```html 50 | 60 | ``` 61 | And then in your `component.ts` file: 62 | 63 | ```ts 64 | import { Component } from '@angular/core'; 65 | import { RavePaymentData } from 'angular-rave'; 66 | 67 | @Component({ 68 | selector: 'app-root', 69 | templateUrl: './app.component.html', 70 | styleUrls: ['./app.component.css'] 71 | }) 72 | export class AppComponent { 73 | paymentFailure() { 74 | console.log('Payment Failed'); 75 | } 76 | 77 | paymentSuccess(res: RavePaymentData) { 78 | console.log('Payment complete', res); 79 | // Verify the transaction 80 | } 81 | 82 | paymentInit() { 83 | console.log('Payment about to begin'); 84 | } 85 | } 86 | 87 | ``` 88 | 89 | ### Rave Options 90 | You can also pass in an object containing your rave options like so 91 | 92 | ```html 93 | 102 | 103 | ``` 104 | And then you can import the `RaveOptions` class for help in typing 105 | ```ts 106 | import { RaveOptions } from 'angular-rave'; 107 | 108 | ... 109 | raveOptions: RaveOptions = { 110 | amount: 3000, 111 | customer: { 112 | email: 'user@ravemail.com', 113 | phonenumber: '09010910901', 114 | name: 'Ekene Ashinze', 115 | }, 116 | customizations: { 117 | description: 'This is a flutterwave modal implemented using angular rave', 118 | title: 'Angular Rave', 119 | logo: 'https://angular.io/assets/images/logos/angular/angular.svg', 120 | }, 121 | tx_ref: `${Math.random() * 1000000}`, 122 | }; 123 | ``` 124 | And then in the template 125 | ```html 126 | 131 | ``` 132 | 133 | ### Rave Key Specificity 134 | Also, you can pass in a key in the component and the directive, in such situation, 135 | this key is given a higher preference over the global `forRoot` key. 136 | For example, if you have this is your module file 137 | 138 | ```ts 139 | @NgModule({ 140 | imports: [ 141 | AngularRaveModule.forRoot('FLWPUBK-1000'), 142 | ] 143 | }) 144 | ``` 145 | and this in your component 146 | ```html 147 | 154 | ``` 155 | Then `FLWPUBK-2000` would be used instead 156 | 157 | **NOTE:** 158 | 159 | - When using the component, the rave's payment popup shows once the component is rendered while using the directive the popup shows on click 160 | - Always generate a sensible unique reference for every transaction (unlike what I did up there 😉) 161 | - After successful payment always perform server verification 162 | 163 | ## OPTIONS 164 | 165 | | Name | Type | Required | Default Value | Description | 166 | |-------------------------|---------------------------|-------------------|:---------------:|:--------------------------------------------------| 167 | | public_key | string | true | - | Merchant public key 168 | | tx_ref | string | true | - | Your transaction reference. This MUST be unique for every transaction 169 | | amount | number | true | - | Amount to charge the customer. 170 | | currency | string | false | 'NGN' | currency to charge in. Defaults to 'NGN' 171 | | integrity_hash | string | false | - | This is a sha256 hash of your FlutterwaveCheckout values, it is used for passing secured values to the payment gateway. 172 | | paymentOptions | `PaymentOptionsEnum[]` | false | - |This specifies the payment options to be displayed e.g - card, mobilemoney, ussd and so on. 173 | | payment_plan | string | false | - | This is the payment plan ID used for Recurring billing 174 | | subaccounts | `RaveSubAcccount[]` | false | - |This is an array of objects containing the subaccount IDs to split the payment into. Check our Split Payment page for more info 175 | | redirect_url | string | false | - | URL to redirect to when a transaction is completed. This is useful for 3DSecure payments so we can redirect your customer back to a custom page you want to show them. 176 | | customer | RaveCustomer | true | - | This is an object that can contains your customer details: e.g: `{ 'email': 'example@example.com', 'phonenumber': '08012345678', 'name': 'Takeshi Kovacs'}` 177 | | meta | `{[key: string]: any}` | false | - | This is an object that helps you include additional payment information to your request `{'consumer_id': 23,'consumer_mac': '92a3-912ba-1192a'}` 178 | | customizations | `RaveCustomization` | true | - | This is an object that contains title, logo, and description you want to display on the modal e.g `{'title': 'Pied Piper Payments', 'description': 'Middleout isn't free. Pay the price', 'logo': 'https://assets.piedpiper.com/logo.png'}` 179 | | init | `() => void` | false | - | A function to be called when payment is about to begin 180 | | onclose | function() | false | - | A function to be called when the pay modal is closed before a transaction is completed. 181 | | callback | (res: RavePaymentData) => void | true | - | A function to be called on successful card charge. Users can always be redirected to a successful or failed page supplied by the merchant here based on response. 182 | 183 | > You can get more information from [rave's documentation](https://flutterwavedevelopers.readme.io/) 184 | > Type definitions can be found [here](./projects/angular-rave/src/lib/rave-options.ts) 185 | 186 | ## CONTRIBUTING 187 | 188 | Feel free to create issues and submit pull requests to make corrections or enhance functionality 189 | 190 | Two projects exist in this repository 191 | - The `Angular-rave` package: [`./projects/angular-rave`](./projects/angular-rave) 192 | - The `Angular-rave-lib` demo: [`./src`](./src) 193 | 194 | ### Angular-rave project 195 | - Found at `./projects/angular-rave/src/lib`. 196 | - The artifacts ([README.md](./projects/angular-rave/README.md), [CHANGELOG.md](./projects/angular-rave/CHANGELOG.md) and [LICENSE.md](./projects/angular-rave/LICENSE.md)) in the `./projects/angular-rave/` folder are overwritten on [build](./package.json#L7) 197 | - Running `npm run build` on the main folder builds this project by [default](./angular.json#L155) 198 | 199 | ### Demo 200 | - To serve this project run `npm start`/`ng serve`. 201 | - This project makes use of the [built package](./tsconfig.json#L23) from the `angular-rave` library for quick testing and real-life debugging. So it's **important** to initially run `npm run build`/`ng build` before serving this project 202 | - To build this project, run `npm run build angular-rave-lib`. The compiled files are built to the `docs` folder for GitHub Pages. 203 | - This project is also served on github pages at https://ashinzekene.github.io/angular-rave/ 204 | 205 | ## Release 206 | - Checkout to a new release branch `release/new-version` eg `release/3.0.0` 207 | - cd into `projects/angular-rave` 208 | - Run `npm version patch|minor|major` 209 | - cd into the main directory and run `npm build` 210 | - Run `git add . && git commit -m new-version` 211 | - Run `git tag -a new-version "release notes..."` 212 | - cd into `dist/angular-rave` and run `npm publish` 213 | 214 | Thanks! 215 | Ashinze Ekene. 216 | 217 | ## License 218 | 219 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 220 | -------------------------------------------------------------------------------- /docs/styles-es2015.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["./node_modules/css-loader/dist/runtime/api.js","./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack:///./src/styles.css?bf74","./src/styles.css"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;;AAEhB;AACA;AACA;;AAEA;AACA,4CAA4C,qBAAqB;AACjE;;AAEA;AACA,KAAK;AACL,IAAI;AACJ;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,qBAAqB,iBAAiB;AACtC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,oBAAoB,qBAAqB;AACzC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,8BAA8B;;AAE9B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA,CAAC;;;AAGD;AACA;AACA;AACA,qDAAqD,cAAc;AACnE;AACA,C;;;;;;;;;;;;AC7Fa;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,uDAAuD;;AAEvD;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;;AAEA,iBAAiB,wBAAwB;AACzC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,gBAAgB,KAAwC,GAAG,sBAAiB,GAAG,SAAI;;AAEnF;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,qEAAqE,qBAAqB,aAAa;;AAEvG;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA,yDAAyD;AACzD,GAAG;;AAEH;;;AAGA;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA,0BAA0B;AAC1B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,mBAAmB,4BAA4B;AAC/C;AACA;AACA;AACA;;AAEA;;AAEA,oBAAoB,6BAA6B;AACjD;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,E;;;;;;;;;;;AC5QA,UAAU,mBAAO,CAAC,mFAAwE;AAC1F,0BAA0B,mBAAO,CAAC,0HAAwH;;AAE1J;;AAEA;AACA,0BAA0B,QAAS;AACnC;;AAEA;;AAEA;AACA;;AAEA;;;;AAIA,sC;;;;;;;;;;;;AClBA;AAAA;AAAA;AAAA;AACyF;AACzF,8BAA8B,mFAA2B;AACzD;AACA,8BAA8B,QAAS,6FAA6F,gNAAgN;AACpV;AACe,sFAAuB,EAAC","file":"styles-es2015.js","sourcesContent":["\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (useSourceMap) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item, useSourceMap);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join('');\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === 'string') {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, '']];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};\n\nfunction cssWithMappingToString(item, useSourceMap) {\n var content = item[1] || ''; // eslint-disable-next-line prefer-destructuring\n\n var cssMapping = item[3];\n\n if (!cssMapping) {\n return content;\n }\n\n if (useSourceMap && typeof btoa === 'function') {\n var sourceMapping = toComment(cssMapping);\n var sourceURLs = cssMapping.sources.map(function (source) {\n return \"/*# sourceURL=\".concat(cssMapping.sourceRoot || '').concat(source, \" */\");\n });\n return [content].concat(sourceURLs).concat([sourceMapping]).join('\\n');\n }\n\n return [content].join('\\n');\n} // Adapted from convert-source-map (MIT)\n\n\nfunction toComment(sourceMap) {\n // eslint-disable-next-line no-undef\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n return \"/*# \".concat(data, \" */\");\n}","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && btoa) {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of