socialnetworknews-web

A open-source Paper.li clone
git clone git://archive.git.mtrnord.blog/SocialNetworkNews/socialnetworknews-web.git
Log | Files | Refs | README | LICENSE

commit 2789f1726e66aa0eecf27a8691ce8e5ecd16bb39
parent 37320834973d3359bd5e92f38ae5fb8bd88bfafe
Author: MTRNord <mtrnord1@gmail.com>
Date:   Fri,  9 Feb 2018 22:32:01 +0100

Initial Scaffold

Signed-off-by: MTRNord <mtrnord1@gmail.com>

Diffstat:
M.angular-cli.json | 16++++++++++++----
Mpackage.json | 11++++++++++-
Msrc/app/app.component.html | 21+--------------------
Rsrc/app/app.component.css -> src/app/app.component.scss | 0
Msrc/app/app.component.ts | 6+++---
Msrc/app/app.module.ts | 38+++++++++++++++++++++++++++++++++-----
Asrc/app/app.routing.ts | 31+++++++++++++++++++++++++++++++
Asrc/app/main/main.component.html | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/main/main.component.scss | 15+++++++++++++++
Asrc/app/main/main.component.spec.ts | 25+++++++++++++++++++++++++
Asrc/app/main/main.component.ts | 13+++++++++++++
Asrc/app/paper/paper.component.html | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/paper/paper.component.scss | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/paper/paper.component.spec.ts | 25+++++++++++++++++++++++++
Asrc/app/paper/paper.component.ts | 24++++++++++++++++++++++++
Asrc/app/papers/papers.component.html | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/papers/papers.component.scss | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/papers/papers.component.spec.ts | 25+++++++++++++++++++++++++
Asrc/app/papers/papers.component.ts | 23+++++++++++++++++++++++
Asrc/app/utils/scrollbar/index.ts | 2++
Asrc/app/utils/scrollbar/scrollbar.component.html | 14++++++++++++++
Asrc/app/utils/scrollbar/scrollbar.component.scss | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/utils/scrollbar/scrollbar.component.ts | 363+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/app/utils/scrollbar/scrollbar.module.ts | 11+++++++++++
Msrc/index.html | 3++-
Msrc/main.ts | 2++
Asrc/ngsw-config.json | 25+++++++++++++++++++++++++
Msrc/polyfills.ts | 12+++++-------
Dsrc/styles.css | 1-
Asrc/styles.scss | 2++
Mtsconfig.json | 3++-
Mtslint.json | 2+-
Myarn.lock | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
33 files changed, 1266 insertions(+), 45 deletions(-)

diff --git a/.angular-cli.json b/.angular-cli.json @@ -11,6 +11,7 @@ "assets", "favicon.ico" ], + "serviceWorker": false, "index": "index.html", "main": "main.ts", "polyfills": "polyfills.ts", @@ -19,9 +20,15 @@ "testTsconfig": "tsconfig.spec.json", "prefix": "app", "styles": [ - "styles.css" + "../node_modules/font-awesome/scss/font-awesome.scss", + "../node_modules/angular-bootstrap-md/scss/bootstrap/bootstrap.scss", + "../node_modules/angular-bootstrap-md/scss/mdb-free.scss", + "./styles.scss" + ], + "scripts": [ + "../node_modules/chart.js/dist/Chart.js", + "../node_modules/hammerjs/hammer.min.js" ], - "scripts": [], "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.ts", @@ -54,7 +61,8 @@ } }, "defaults": { - "styleExt": "css", - "component": {} + "styleExt": "scss", + "component": { + } } } diff --git a/package.json b/package.json @@ -5,7 +5,7 @@ "scripts": { "ng": "ng", "start": "ng serve", - "build": "ng build --prod", + "build": "ng build --prod --aot=false", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" @@ -13,6 +13,7 @@ "private": true, "dependencies": { "@angular/animations": "^5.0.0", + "@angular/cdk": "^5.2.0", "@angular/common": "^5.0.0", "@angular/compiler": "^5.0.0", "@angular/core": "^5.0.0", @@ -21,11 +22,19 @@ "@angular/platform-browser": "^5.0.0", "@angular/platform-browser-dynamic": "^5.0.0", "@angular/router": "^5.0.0", + "@angular/service-worker": "^5.2.4", + "angular-bootstrap-md": "^5.1.2", + "chart.js": "2.5.0", "core-js": "^2.4.1", + "font-awesome": "^4.7.0", + "hammerjs": "^2.0.8", + "ng-gallery": "^1.0.1", "rxjs": "^5.5.2", + "web-animations-js": "^2.3.1", "zone.js": "^0.8.14" }, "devDependencies": { + "@angular-devkit/core": "^0.3.1", "@angular/cli": "1.6.1", "@angular/compiler-cli": "^5.0.0", "@angular/language-service": "^5.0.0", diff --git a/src/app/app.component.html b/src/app/app.component.html @@ -1,20 +1 @@ -<!--The content below is only a placeholder and can be replaced.--> -<div style="text-align:center"> - <h1> - Welcome to {{ title }}! - </h1> - <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="> -</div> -<h2>Here are some links to help you start: </h2> -<ul> - <li> - <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> - </li> - <li> - <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2> - </li> - <li> - <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2> - </li> -</ul> - +<router-outlet></router-outlet> diff --git a/src/app/app.component.css b/src/app/app.component.scss diff --git a/src/app/app.component.ts b/src/app/app.component.ts @@ -1,10 +1,10 @@ -import { Component } from '@angular/core'; +import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.scss'] }) export class AppComponent { - title = 'app'; + } diff --git a/src/app/app.module.ts b/src/app/app.module.ts @@ -1,18 +1,46 @@ import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import {NgModule, NO_ERRORS_SCHEMA} from '@angular/core'; +import { MDBBootstrapModule } from 'angular-bootstrap-md'; +import { ScrollbarModule } from './utils/scrollbar'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import {GalleryConfig, GalleryModule} from 'ng-gallery'; import { AppComponent } from './app.component'; +import { MainComponent } from './main/main.component'; +import {AppRoutingModule} from './app.routing'; +import { PaperComponent } from './paper/paper.component'; +import { PapersComponent } from './papers/papers.component'; +export const config: GalleryConfig = { + 'gestures': true, + 'thumbnails': null, + 'navigation': null, + 'imageSize': 'contain', + 'style': { + 'padding-top': '30px' + }, +}; + @NgModule({ declarations: [ - AppComponent + AppComponent, + MainComponent, + PaperComponent, + PapersComponent, ], imports: [ - BrowserModule + BrowserModule, + MDBBootstrapModule.forRoot(), + AppRoutingModule, + ScrollbarModule, + BrowserAnimationsModule, + GalleryModule.forRoot(config), + ], + providers: [ ], - providers: [], - bootstrap: [AppComponent] + bootstrap: [AppComponent], + schemas: [ NO_ERRORS_SCHEMA ] }) export class AppModule { } diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts @@ -0,0 +1,31 @@ +import {RouterModule, Routes} from '@angular/router'; +import {MainComponent} from './main/main.component'; +import {NgModule} from '@angular/core'; +import {PaperComponent} from './paper/paper.component'; +import {PapersComponent} from './papers/papers.component'; + +const routes: Routes = [ + { + path: '', + component: MainComponent, + }, + { + path: 'paper/:paperUUID', + component: PaperComponent, + }, + { + path: 'papers', + component: PapersComponent, + }, +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(routes) + ], + exports: [ + RouterModule + ], + declarations: [] +}) +export class AppRoutingModule { } diff --git a/src/app/main/main.component.html b/src/app/main/main.component.html @@ -0,0 +1,51 @@ +<header> + <mdb-navbar SideClass="navbar fixed-top navbar-expand-lg navbar-dark scrolling-navbar" [containerInside]="false"> + <logo> + <a class="logo navbar-brand" href="#"><strong>Social Networks News</strong></a> + </logo> + <links> + <ul class="navbar-nav mr-auto"> + <li class="nav-item active waves-light" mdbRippleRadius> + <a class="nav-link" routerLink="" routerLinkActive="active">Home <span class="sr-only">(current)</span></a> + </li> + <li class="nav-item waves-light" mdbRippleRadius> + <a class="nav-link">Features</a> + </li> + <li class="nav-item waves-light" mdbRippleRadius> + <a class="nav-link" routerLink="/papers" routerLinkActive="active">Papers</a> + </li> + </ul> + </links> + </mdb-navbar> + <!-- Main --> + <div class="view intro hm-purple-light" style=""> + <div class="full-bg-img flex-center"> + <div class="container text-center white-text wow fadeInUp"> + <h2>Social Networks News is a FOSS App to generate a Newspaper of your needs</h2> + <br> + <h5>It happens automatic based on your Hashtags and Lists</h5> + <p>You will find the most amusing or interesting content of your hashtag</p> + <br> + <p>Already prepared and baked to be ready to be read by you!</p> + </div> + </div> + </div> + <!-- /.Main --> +</header> +<!--Main Navigation--> + +<!--Main Layout--> +<main class="text-center py-5"> + + <div class="container"> + <div class="row"> + <div class="col-md-12"> + + <p align="justify">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> + + </div> + </div> + </div> + +</main> +<!--Main Layout--> diff --git a/src/app/main/main.component.scss b/src/app/main/main.component.scss @@ -0,0 +1,15 @@ +.view { + background: url("https://mdbootstrap.com/img/Photos/Others/img (40).jpg")no-repeat center center; + background-size: cover; +} +.navbar { + background-color: transparent; +} +.top-nav-collapse { + background-color: #4285F4; +} +@media only screen and (max-width: 768px) { + .navbar { + background-color: #4285F4; + } +} diff --git a/src/app/main/main.component.spec.ts b/src/app/main/main.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MainComponent } from './main.component'; + +describe('MainComponent', () => { + let component: MainComponent; + let fixture: ComponentFixture<MainComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MainComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MainComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts @@ -0,0 +1,13 @@ +import {Component, ViewEncapsulation} from '@angular/core'; + +@Component({ + selector: 'app-main', + templateUrl: './main.component.html', + styleUrls: ['./main.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class MainComponent { + + constructor() { } + +} diff --git a/src/app/paper/paper.component.html b/src/app/paper/paper.component.html @@ -0,0 +1,74 @@ +<header> + <mdb-navbar SideClass="navbar fixed-top navbar-expand-lg navbar-dark scrolling-navbar" [containerInside]="false"> + <logo> + <a class="logo navbar-brand" href="#"><strong>Social Networks News</strong></a> + </logo> + <links> + <ul class="navbar-nav mr-auto"> + <li class="nav-item waves-light" mdbRippleRadius> + <a class="nav-link" routerLink="">Home</a> + </li> + <li class="nav-item waves-light" mdbRippleRadius> + <a class="nav-link">Features</a> + </li> + <li class="nav-item active waves-light" mdbRippleRadius> + <a class="nav-link" routerLink="/papers" routerLinkActive="active">Papers <span class="sr-only">(current)</span></a> + </li> + </ul> + </links> + </mdb-navbar> + <!-- Main --> + <div class="view intro hm-purple-light" style=""> + <div class="full-bg-img flex-center"> + <div class="container text-center white-text wow fadeInUp"> + <h2>{{paperTitle}}</h2> + <br> + <h5>{{paperSubtitle}}</h5> + </div> + </div> + </div> + <!-- /.Main --> +</header> +<!--Main Navigation--> + +<!--Main Layout--> +<main class="text-center py-5"> + + <div class="container" gallerize> + <div class="card-deck" *ngFor="let rows of chunkedData"> + <div class="card card-cascade" *ngFor="let item of rows"> + <!--Retweet Badge--> + <div class="card-ribbon card-ribbon-top card-ribbon-left tblue" *ngIf="item.retweet == true"> + <i class="fa fa-retweet"></i> + </div> + <!--Card image--> + <div class="overlay hm-white-slight waves-light card-img-top" *ngIf="item.imageURL"> + <img [src]="item.imageURL" class="img-fluid" style="z-index: 0"> + <a> + <div class="mask"></div> + </a> + </div> + <!--Card content--> + <div class="card-body"> + <!--Title when Text exists--> + <h4 class="card-title text-left" *ngIf="(item.text && item.imageURL) || (item.text && !item.imageURL)"><a href="{{item.userLink}}">{{item.title}}</a></h4> + <!--Title when no Text exists--> + <h4 class="card-title align-middle" *ngIf="!item.text || !item.imageURL"><a href="{{item.userLink}}">{{item.title}}</a></h4> + <!--Text--> + <p class="card-text text-justify" *ngIf="item.text">{{item.text}}</p> + </div> + <!-- Card footer --> + <div class="card-data"> + <ul> + <li><i class="fa fa-clock-o">&nbsp;</i>{{item.createdAt}}</li>&nbsp; + <li><i class="fa fa-comments-o">&nbsp;</i>{{item.replies}}</li>&nbsp; + <li><i class="fa fa-heart">&nbsp;</i>{{item.favs}}</li>&nbsp; + <li><i class="fa fa-retweet">&nbsp;</i>{{item.retweets}}</li>&nbsp; + </ul> + </div> + </div> + </div> + </div> + +</main> +<!--Main Layout--> diff --git a/src/app/paper/paper.component.scss b/src/app/paper/paper.component.scss @@ -0,0 +1,129 @@ +.view{ + background: url("https://mdbootstrap.com/img/Photos/Others/img (40).jpg")no-repeat center center; + background-size: cover; +} +.navbar { + background-color: transparent; +} +.top-nav-collapse { + background-color: #4285F4; +} +@media only screen and (max-width: 768px) { + .navbar { + background-color: #4285F4; + } +} + +.card { + overflow: hidden; +} + +.card .card-data { + background-color: #929fba; + color: #fff; + text-align: center; + height: auto; + padding: 10px; +} + +.card .card-data ul { + margin-bottom: 0; + font-size: .9rem; +} + +.card .card-data ul li { + display: inline; +} + +.card .card-data ul a { + color: #fff; +} + +.card .card-data ul a .fa { + margin-left: 5px; + margin-right: 3px; +} + +.card.card-cascade { + width: 100%; +} + +.card-img-top { + width: 100%; + height: 20vw; + object-fit: cover; +} + +.card-img-top img { + width: 100%; + height: 18.5vw; + object-fit: cover; +} + +.card .card-body { + z-index: 1; + background-color: white; +} + +.card:not([class*="card-outline-"]) { + border: 0; +} + +#toast-container > div, .author-box, .badge, .btn, .card-wrapper .back, .card-wrapper .front, .card.card-cascade.wider .card-body, .card:not([class*="card-outline-"]), .chip, .counter, .dropdown-content, .jumbotron, .md-pills .nav-link.active, .modal-dialog.cascading-modal .modal-c-tabs .nav-tabs, .modal-dialog.modal-notify .modal-header, .navbar, .pagination .active .page-link, .pricing-card .price .version, .section-blog-fw img, .side-nav, .social-list, .z-depth-1 { + box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12); +} + +.btn-floating:hover, .card-overlay, .card.card-cascade img, .colorful-select .dropdown-content li a:hover, .colorful-select .dropdown-content li span:hover, .comments-list img, .modal-dialog.cascading-modal.modal-avatar .modal-header img, .reply-form img, .testimonial-carousel .testimonial .avatar img, .z-depth-2 { + box-shadow: 0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19); +} + +.card.card-cascade img { + border-radius: 4px; +} + +.waves-effect { + position: relative; + cursor: pointer; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + z-index: 1; +} + +/* The ribbons by https://codepen.io/eode9/pen/twkKm*/ + +.card-ribbon-bottom.card-ribbon-right, .card-ribbon-top.card-ribbon-left { + -webkit-transform: rotate(-45deg); + -ms-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +.card-ribbon-left { + left: -70px; +} + +.card-ribbon-top { + top: 20px; +} + +.card-ribbon:after { + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} + +.card-ribbon { + width: 200px; + padding: 2px 5px; + position: absolute; + text-align: center; + font-size: 12px; + z-index: 1; +} + +.card-ribbon.tblue { + background-color: #1da1f2; +} diff --git a/src/app/paper/paper.component.spec.ts b/src/app/paper/paper.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PaperComponent } from './paper.component'; + +describe('PaperComponent', () => { + let component: PaperComponent; + let fixture: ComponentFixture<PaperComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PaperComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PaperComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/paper/paper.component.ts b/src/app/paper/paper.component.ts @@ -0,0 +1,24 @@ +import {Component, ViewEncapsulation} from '@angular/core'; + +@Component({ + selector: 'app-paper', + templateUrl: './paper.component.html', + styleUrls: ['./paper.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class PaperComponent { + paperTitle = 'Test Paper'; + paperSubtitle = 'Something to test'; + testData = [{title: 'Simon Wüllhorst', 'userLink': 'https://twitter.com/des_cilla', text: 'Yaay, neue LTE-Antennen sind da. Es gibt bald endlich wieder schnelles Internet auf dem Dorf. :) #Freifunk', imageURL: 'https://pbs.twimg.com/media/DVmb2UCWsAA8oTD.jpg', createdAt: '09.02.2018', replies: 0, favs: 2, retweets: 1}, {title: 'Jason Scott', retweet: true, 'userLink': 'https://twitter.com/textfiles', imageURL: 'https://pbs.twimg.com/media/DVZ5gw0U0AA_mOu.jpg', createdAt: '07.02.2018', replies: 75, favs: 8003, retweets: 2813}, {title: 'Christian Dresel', 'userLink': 'https://twitter.com/DreselChristian', text: 'Soviel Richtfunk (blaue Linien)... soooo geiiiilllll :) @freifunk @FreifunkFranken #freifunk', imageURL: 'https://pbs.twimg.com/media/DViJcIRX0AAk1TT.jpg:large', createdAt: '08.02.2018', replies: 1, favs: 3, retweets: 0}]; + chunkedData = PaperComponent.chunk(this.testData, 3); + + constructor() { } + + static chunk(arr, size) { + const newArr = []; + for (let i = 0; i < arr.length; i += size) { + newArr.push(arr.slice(i, i + size)); + } + return newArr; + } +} diff --git a/src/app/papers/papers.component.html b/src/app/papers/papers.component.html @@ -0,0 +1,61 @@ +<header> + <mdb-navbar SideClass="navbar fixed-top navbar-expand-lg navbar-dark scrolling-navbar" [containerInside]="false"> + <logo> + <a class="logo navbar-brand" href="#"><strong>Social Networks News</strong></a> + </logo> + <links> + <ul class="navbar-nav mr-auto"> + <li class="nav-item waves-light" mdbRippleRadius> + <a class="nav-link" routerLink="">Home</a> + </li> + <li class="nav-item waves-light" mdbRippleRadius> + <a class="nav-link">Features</a> + </li> + <li class="nav-item active waves-light" mdbRippleRadius> + <a class="nav-link" routerLink="/papers" routerLinkActive="active">Papers <span class="sr-only">(current)</span></a> + </li> + </ul> + </links> + </mdb-navbar> + <!-- Main --> + <div class="view intro hm-purple-light" style=""> + <div class="full-bg-img flex-center"> + <div class="container text-center white-text wow fadeInUp"> + <h2>{{pageTitle}}</h2> + <br> + <h5>{{pageSubtitle}}</h5> + </div> + </div> + </div> + <!-- /.Main --> +</header> +<!--Main Navigation--> + +<!--Main Layout--> +<main class="text-center py-5"> + + <div class="container" gallerize> + <div class="card-deck" *ngFor="let rows of chunkedData"> + <div class="card card-cascade mx-auto" *ngFor="let item of rows" style="max-width: 33.33%"> + <!--Card image--> + <div class="overlay hm-white-slight waves-light card-img-top" *ngIf="item.logoURL"> + <img [src]="item.logoURL" class="img-fluid" style="z-index: 0"> + <a> + <div class="mask"></div> + </a> + </div> + <!--Card content--> + <div class="card-body"> + <!--Title when Text exists--> + <h4 class="card-title text-left" *ngIf="(item.description && item.logoURL) || (item.description && !item.logoURL)"><a routerLink="/paper/{{item.uuid}}">{{item.title}}</a></h4> + <!--Title when no Text exists--> + <h4 class="card-title align-middle" *ngIf="!item.description || !item.logoURL"><a routerLink="/paper/{{item.uuid}}">{{item.title}}</a></h4> + <!--Text--> + <p class="card-text text-justify" *ngIf="item.description">{{item.description}}</p> + </div> + </div> + </div> + </div> + +</main> +<!--Main Layout--> diff --git a/src/app/papers/papers.component.scss b/src/app/papers/papers.component.scss @@ -0,0 +1,129 @@ +.view{ + background: url("https://mdbootstrap.com/img/Photos/Others/img (40).jpg")no-repeat center center; + background-size: cover; +} +.navbar { + background-color: transparent; +} +.top-nav-collapse { + background-color: #4285F4; +} +@media only screen and (max-width: 768px) { + .navbar { + background-color: #4285F4; + } +} + +.card { + overflow: hidden; +} + +.card .card-data { + background-color: #929fba; + color: #fff; + text-align: center; + height: auto; + padding: 10px; +} + +.card .card-data ul { + margin-bottom: 0; + font-size: .9rem; +} + +.card .card-data ul li { + display: inline; +} + +.card .card-data ul a { + color: #fff; +} + +.card .card-data ul a .fa { + margin-left: 5px; + margin-right: 3px; +} + +.card.card-cascade { + width: 100%; +} + +.card-img-top { + width: 100%; + height: 20vw; + object-fit: cover; +} + +.card-img-top img { + width: 100%; + height: 18.5vw; + object-fit: cover; +} + +.card .card-body { + z-index: 1; + background-color: white; +} + +.card:not([class*="card-outline-"]) { + border: 0; +} + +#toast-container > div, .author-box, .badge, .btn, .card-wrapper .back, .card-wrapper .front, .card.card-cascade.wider .card-body, .card:not([class*="card-outline-"]), .chip, .counter, .dropdown-content, .jumbotron, .md-pills .nav-link.active, .modal-dialog.cascading-modal .modal-c-tabs .nav-tabs, .modal-dialog.modal-notify .modal-header, .navbar, .pagination .active .page-link, .pricing-card .price .version, .section-blog-fw img, .side-nav, .social-list, .z-depth-1 { + box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12); +} + +.btn-floating:hover, .card-overlay, .card.card-cascade img, .colorful-select .dropdown-content li a:hover, .colorful-select .dropdown-content li span:hover, .comments-list img, .modal-dialog.cascading-modal.modal-avatar .modal-header img, .reply-form img, .testimonial-carousel .testimonial .avatar img, .z-depth-2 { + box-shadow: 0 8px 17px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.19); +} + +.card.card-cascade img { + border-radius: 4px; +} + +.waves-effect { + position: relative; + cursor: pointer; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + z-index: 1; +} + +/* The ribbons by https://codepen.io/eode9/pen/twkKm*/ + +.card-ribbon-bottom.card-ribbon-right, .card-ribbon-top.card-ribbon-left { + -webkit-transform: rotate(-45deg); + -ms-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +.card-ribbon-left { + left: -70px; +} + +.card-ribbon-top { + top: 20px; +} + +.card-ribbon:after { + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} + +.card-ribbon { + width: 200px; + padding: 2px 5px; + position: absolute; + text-align: center; + font-size: 12px; + z-index: 1; +} + +.card-ribbon.tblue { + background-color: #1da1f2; +} diff --git a/src/app/papers/papers.component.spec.ts b/src/app/papers/papers.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PapersComponent } from './papers.component'; + +describe('PapersComponent', () => { + let component: PapersComponent; + let fixture: ComponentFixture<PapersComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PapersComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PapersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/papers/papers.component.ts b/src/app/papers/papers.component.ts @@ -0,0 +1,23 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-papers', + templateUrl: './papers.component.html', + styleUrls: ['./papers.component.scss'] +}) +export class PapersComponent { + pageTitle = 'Find Papers'; + pageSubtitle = 'Get the full blast of different Newspapers'; + testData = [{title: 'Freifunk News', uuid: 0, logoURL: 'https://blog.freifunk.net/wp-content/uploads/2017/03/Freifunk.net_.svg_.png', description: ''}]; + chunkedData = PapersComponent.chunk(this.testData, 3); + + constructor() { } + static chunk(arr, size) { + const newArr = []; + for (let i = 0; i < arr.length; i += size) { + newArr.push(arr.slice(i, i + size)); + } + return newArr; + } + +} diff --git a/src/app/utils/scrollbar/index.ts b/src/app/utils/scrollbar/index.ts @@ -0,0 +1,2 @@ +export { ScrollbarModule } from './scrollbar.module'; +export { ScrollbarComponent } from './scrollbar.component'; diff --git a/src/app/utils/scrollbar/scrollbar.component.html b/src/app/utils/scrollbar/scrollbar.component.html @@ -0,0 +1,14 @@ +<div class="ng-scrollbar-container" [class.ng-scrollbar-autohide]="autoHide"> + + <div #barX class="ng-scrollbar -horizontal {{barClass}}" [class.ng-scrollbar-disabled]="!trackX"> + <div #thumbX class="ng-scrollbar-thumb {{thumbClass}}"></div> + </div> + + <div #barY class="ng-scrollbar -vertical {{barClass}}" [class.ng-scrollbar-disabled]="!trackY"> + <div #thumbY class="ng-scrollbar-thumb {{thumbClass}}"></div> + </div> + + <div #view class="ng-scrollbar-view {{viewClass}}"> + <ng-content></ng-content> + </div> +</div> diff --git a/src/app/utils/scrollbar/scrollbar.component.scss b/src/app/utils/scrollbar/scrollbar.component.scss @@ -0,0 +1,77 @@ +ng-scrollbar { + display: block; + position: relative; + height: 100%; + overflow: hidden !important; +} + +.ng-scrollbar-container { + position: relative; + overflow: hidden !important; + width: 100%; + height: 100%; +} + +.ng-scrollbar-autohide > .ng-scrollbar { + opacity: 0; + transition: opacity 120ms ease-out; +} + +.ng-scrollbar-autohide:hover > .ng-scrollbar, +.ng-scrollbar-autohide:active > .ng-scrollbar, +.ng-scrollbar-autohide:focus > .ng-scrollbar { + opacity: 1; + transition: opacity 340ms ease-out; +} + +.ng-scrollbar { + position: absolute; + right: 2px; + bottom: 2px; + z-index: 1; + border-radius: 3px; +} + +.-vertical { + width: 6px; + top: 2px; + .ng-scrollbar-thumb { + width: 100%; + } +} + +.-horizontal { + height: 6px; + left: 2px; + .ng-scrollbar-thumb { + height: 100%; + } +} + +.ng-scrollbar-disabled { + display: none; +} + +.ng-scrollbar-thumb { + position: relative; + display: block; + width: 0; + height: 0; + cursor: pointer; + border-radius: inherit; + background-color: rgba(0, 0, 0, .2); + transform: translate3d(0, 0, 0); + + &:hover, + &:active { + background-color: rgba(0, 0, 0, .3); + } +} + +.ng-scrollbar-view { + width: 100%; + height: 100%; + overflow: scroll; + transform: translate3d(0, 0, 0); + -webkit-overflow-scrolling: touch; +} diff --git a/src/app/utils/scrollbar/scrollbar.component.ts b/src/app/utils/scrollbar/scrollbar.component.ts @@ -0,0 +1,363 @@ +import { + Component, + Inject, + ChangeDetectionStrategy, + AfterViewInit, + OnDestroy, + Input, + Output, + EventEmitter, + ViewChild, + Renderer2, + ViewEncapsulation, + NgZone +} from '@angular/core'; +import { DOCUMENT } from '@angular/common'; +import { Subscription } from 'rxjs/Subscription'; +import { of } from 'rxjs/observable/of'; +import { fromEvent } from 'rxjs/observable/fromEvent'; +import { empty } from 'rxjs/observable/empty'; +import { takeWhile, expand, delay } from 'rxjs/operators'; + +@Component({ + selector: 'ng-scrollbar', + templateUrl: 'scrollbar.component.html', + styleUrls: ['scrollbar.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, + preserveWhitespaces: false +}) +export class ScrollbarComponent implements AfterViewInit, OnDestroy { + + private _thumbSizeY = 0; + private _thumbSizeX = 0; + private _trackTopMax = 0; + private _trackLeftMax = 0; + private _scrollLeftMax = 0; + private _scrollTopMax = 0; + private _naturalThumbSizeY = 0; + private _naturalThumbSizeX = 0; + private _prevPageY = 0; + private _prevPageX = 0; + private _currXPos = 0; + private _currYPos = 0; + private minThumbSize = 20; + private scrollSub$: Subscription; + private barXSub$: Subscription; + private barYSub$: Subscription; + private thumbXSub$: Subscription; + private thumbYSub$: Subscription; + private observer: MutationObserver; + + barX: HTMLElement; + barY: HTMLElement; + thumbX: HTMLElement; + thumbY: HTMLElement; + view: HTMLElement; + + @ViewChild('barX') barXRef; + @ViewChild('barY') barYRef; + @ViewChild('thumbX') thumbXRef; + @ViewChild('thumbY') thumbYRef; + @ViewChild('view') viewRef; + + @Input() autoUpdate = true; + @Input() autoHide = false; + @Input() trackX = false; + @Input() trackY = true; + @Input() viewClass: string; + @Input() barClass: string; + @Input() thumbClass: string; + @Output() scrollState = new EventEmitter<any>(); + + constructor(private zone: NgZone, private renderer: Renderer2, @Inject(DOCUMENT) private document: any) { + } + + ngAfterViewInit() { + + this.zone.runOutsideAngular(() => { + this.barX = this.barXRef.nativeElement; + this.barY = this.barYRef.nativeElement; + this.thumbX = this.thumbXRef.nativeElement; + this.thumbY = this.thumbYRef.nativeElement; + this.view = this.viewRef.nativeElement; + + this.hideNativeScrollbars(); + + /** Initialize scrollbars */ + this.scrollWorker(null); + + this.scrollSub$ = fromEvent(this.view, 'scroll', (e) => this.scrollWorker(e)).subscribe(); + if (this.trackX) { + this.barXSub$ = fromEvent(this.barX, 'mousedown', (e) => this.barXWorker(e)).subscribe(); + this.thumbXSub$ = fromEvent(this.thumbX, 'mousedown', (e) => this.thumbXWorker(e)).subscribe(); + } + if (this.trackY) { + this.barYSub$ = fromEvent(this.barY, 'mousedown', (e) => this.barYWorker(e)).subscribe(); + this.thumbYSub$ = fromEvent(this.thumbY, 'mousedown', (e) => this.thumbYWorker(e)).subscribe(); + } + + if (this.autoUpdate) { + /** Observe content changes */ + this.observer = new MutationObserver(() => this.update()); + this.observer.observe(this.view, { subtree: true, childList: true }); + } + }); + } + + ngOnDestroy() { + this.scrollSub$.unsubscribe(); + if (this.trackX) { + this.barXSub$.unsubscribe(); + this.thumbXSub$.unsubscribe(); + } + if (this.trackY) { + this.barYSub$.unsubscribe(); + this.thumbYSub$.unsubscribe(); + } + if (this.observer) { + this.observer.disconnect(); + } + } + + /** + * Scroll horizontally + * @param to + * @param duration + */ + scrollXTo(to: number, duration = 200) { + + this.zone.runOutsideAngular(() => { + of(duration).pipe( + takeWhile(() => duration > 0), + expand(d => { + if (d > 0) { + const difference = to - this.view.scrollLeft; + const perTick = difference / d * 10; + this.renderer.setProperty(this.view, 'scrollLeft', this.view.scrollLeft + perTick); + return of(d - 10).pipe(delay(10)); + } else { + duration = d; + return empty(); + } + }) + ).subscribe(); + }); + } + + /** + * Scroll vertically + * @param to + * @param duration + */ + scrollYTo(to: number, duration = 200) { + this.zone.runOutsideAngular(() => { + of(duration).pipe( + takeWhile(() => duration > 0), + expand(d => { + if (d > 0) { + const difference = to - this.view.scrollTop; + const perTick = difference / d * 10; + this.renderer.setProperty(this.view, 'scrollTop', this.view.scrollTop + perTick); + return of(d - 10).pipe(delay(10)); + } else { + duration = d; + return empty(); + } + }) + ).subscribe(); + }); + } + + /** + * Update thumbnails + */ + update() { + this.setThumbXPosition(this._currXPos, this.calculateThumbXSize()); + this.setThumbYPosition(this._currYPos, this.calculateThumbYSize()); + } + + /** + * Scroll Worker + * @param e - Mouse Event + */ + private scrollWorker(e: any) { + this._thumbSizeX = this.thumbX.clientWidth; + this._thumbSizeY = this.thumbY.clientHeight; + + this._trackLeftMax = this.barX.clientWidth - this._thumbSizeX; + this._trackTopMax = this.barY.clientHeight - this._thumbSizeY; + + const thumbXPosition = this.view.scrollLeft * this._trackLeftMax / this._scrollLeftMax; + const thumbYPosition = this.view.scrollTop * this._trackTopMax / this._scrollTopMax; + + this.setThumbXPosition(thumbXPosition, this.calculateThumbXSize()); + this.setThumbYPosition(thumbYPosition, this.calculateThumbYSize()); + + /** Emit scroll state */ + this.scrollState.emit(e); + } + + /** + * Horizontal scrollbar click worker + * @param e - Mouse Event + */ + private barXWorker(e: any) { + if (e.target === e.currentTarget) { + const offset = e.offsetX - this._naturalThumbSizeX * .5; + const thumbPositionPercentage = offset * 100 / this.barX.clientWidth; + const scrollLeft = thumbPositionPercentage * this.view.scrollWidth / 100; + this.renderer.setProperty(this.view, 'scrollLeft', scrollLeft); + } + } + + /** + * Vertical scrollbar click worker + * @param e - Mouse Event + */ + private barYWorker(e: any) { + if (e.target === e.currentTarget) { + const offset = e.offsetY - this._naturalThumbSizeY * .5; + const thumbPositionPercentage = offset * 100 / this.barY.clientHeight; + const scrollTop = thumbPositionPercentage * this.view.scrollHeight / 100; + this.renderer.setProperty(this.view, 'scrollTop', scrollTop); + } + } + + /** + * Horizontal thumb worker + * @param e - Mouse Event + */ + private thumbXWorker(e: any) { + + /** Start dragging scrollbar on mouseMove */ + const startDrag = (event: any) => { + this._prevPageX = this._thumbSizeX - e.offsetX; + const offset = event.clientX - this.barX.getBoundingClientRect().left; + const thumbClickPosition = this._thumbSizeX - this._prevPageX; + const scrollLeft = this._scrollLeftMax * (offset - thumbClickPosition) / this._trackLeftMax; + this.renderer.setProperty(this.view, 'scrollLeft', scrollLeft); + }; + + /** Reset and remove listeners on mouseUp */ + const endDrag = () => { + this.document.onselectstart = null; + mouseMoveSub$.unsubscribe(); + mouseUpSub$.unsubscribe(); + this._prevPageX = 0; + }; + + /** Disable selection while dragging scrollbars */ + this.document.onselectstart = () => false; + const mouseMoveSub$ = fromEvent(this.document.body, 'mousemove', startDrag).subscribe(); + const mouseUpSub$ = fromEvent(this.document.body, 'mouseup', endDrag).subscribe(); + } + + /** + * Vertical thumb worker + * @param e - Mouse Event + */ + private thumbYWorker(e: any) { + + /** Start dragging scrollbar on mouseMove */ + const startDrag = (event: any) => { + this._prevPageY = this._thumbSizeY - e.offsetY; + const offset = event.clientY - this.barY.getBoundingClientRect().top; + const thumbClickPosition = this._thumbSizeY - this._prevPageY; + const scrollTop = this._scrollTopMax * (offset - thumbClickPosition) / this._trackTopMax; + this.renderer.setProperty(this.view, 'scrollTop', scrollTop); + }; + + /** Reset and remove listeners on mouseUp */ + const endDrag = () => { + this.document.onselectstart = null; + mouseMoveSub$.unsubscribe(); + mouseUpSub$.unsubscribe(); + this._prevPageY = 0; + }; + + /** Disable selection while dragging scrollbars */ + this.document.onselectstart = () => false; + const mouseMoveSub$ = fromEvent(this.document.body, 'mousemove', startDrag).subscribe(); + const mouseUpSub$ = fromEvent(this.document.body, 'mouseup', endDrag).subscribe(); + } + + /** + * Calculate Thumb X Size + */ + private calculateThumbXSize(): number { + this._naturalThumbSizeX = this.barX.clientWidth / this.view.scrollWidth * this.barX.clientWidth; + this._scrollLeftMax = this.view.scrollWidth - this.view.clientWidth; + return this.scrollBoundaries(this._naturalThumbSizeX, this._scrollLeftMax); + } + + /** + * Calculate Thumb Y Size + */ + private calculateThumbYSize(): number { + this._naturalThumbSizeY = this.barY.clientHeight / this.view.scrollHeight * this.barY.clientHeight; + this._scrollTopMax = this.view.scrollHeight - this.view.clientHeight; + return this.scrollBoundaries(this._naturalThumbSizeY, this._scrollTopMax); + } + + /** + * Get scrollbar thumb size + * @param naturalThumbSize + * @param scrollMax + */ + private scrollBoundaries(naturalThumbSize: number, scrollMax: number): number { + return (naturalThumbSize < this.minThumbSize) ? this.minThumbSize : scrollMax ? naturalThumbSize : 0; + } + + /** + * Set horizontal scrollbar thumb style + * @param x + * @param width + */ + private setThumbXPosition(x: number, width: number) { + const transform = `translate3d(${x}px, 0, 0)`; + this.renderer.setStyle(this.thumbX, 'webkitTransform', transform); + this.renderer.setStyle(this.thumbX, 'transform', transform); + this.renderer.setStyle(this.thumbX, 'width', width + 'px'); + this._currXPos = x; + } + + /** + * Set vertical scrollbar thumb style + * @param y + * @param height + */ + private setThumbYPosition(y: number, height: number) { + const transform = `translate3d(0, ${y}px, 0)`; + this.renderer.setStyle(this.thumbY, 'webkitTransform', transform); + this.renderer.setStyle(this.thumbY, 'transform', transform); + this.renderer.setStyle(this.thumbY, 'height', height + 'px'); + this._currYPos = y; + } + + /** + * Hide native scrollbars + */ + private hideNativeScrollbars() { + const size = `calc(100% + ${this.getNativeScrollbarWidth()}px)`; + this.renderer.setStyle(this.view, 'width', size); + this.renderer.setStyle(this.view, 'height', size); + } + + /** + * Get the native scrollbar width + */ + private getNativeScrollbarWidth(): number { + const element = this.document.createElement('div'); + element.style.position = 'absolute'; + element.style.top = '-9999px'; + element.style.width = '100px'; + element.style.height = '100px'; + element.style.overflow = 'scroll'; + element.style.msOverflowStyle = 'scrollbar'; + this.document.body.appendChild(element); + const sw = element.offsetWidth - element.clientWidth; + this.document.body.removeChild(element); + return sw; + } +} diff --git a/src/app/utils/scrollbar/scrollbar.module.ts b/src/app/utils/scrollbar/scrollbar.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { ScrollbarComponent } from './scrollbar.component'; + +@NgModule({ + imports: [CommonModule], + declarations: [ScrollbarComponent], + exports: [ScrollbarComponent] +}) +export class ScrollbarModule { +} diff --git a/src/index.html b/src/index.html @@ -7,8 +7,9 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> + <link href="https://fonts.googleapis.com/css?family=Lora" rel="stylesheet"> </head> -<body> +<body style="font-family: 'Lora', serif !important;"> <app-root></app-root> </body> </html> diff --git a/src/main.ts b/src/main.ts @@ -4,6 +4,8 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +import 'hammerjs'; + if (environment.production) { enableProdMode(); } diff --git a/src/ngsw-config.json b/src/ngsw-config.json @@ -0,0 +1,25 @@ +{ + "index": "/index.html", + "appData": { + "test": true + }, + "assetGroups": [{ + "name": "appshell", + "resources": { + "files": [ + "/assets/**/*", + "!/ngsw-worker.js" + ], + "versionedFiles": [ + "/**/*.html", + "/**/*.js", + "/**/*.css" + ], + "urls": [ + "https://fonts.googleapis.com/css?family=Material+Icons", + "https://fonts.gstatic.com/s/materialicons/v29/2fcrYFNaTjcS6g4U3t-Y5UEw0lE80llgEseQY3FEmqw.woff2" + ] + } + }], + "dataGroups": [] +} diff --git a/src/polyfills.ts b/src/polyfills.ts @@ -15,6 +15,10 @@ */ /*************************************************************************************************** + * APPLICATION IMPORTS + */ + +/*************************************************************************************************** * BROWSER POLYFILLS */ @@ -50,7 +54,7 @@ import 'core-js/es7/reflect'; * Required to support Web Animations `@angular/platform-browser/animations`. * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation **/ -// import 'web-animations-js'; // Run `npm install --save web-animations-js`. +import 'web-animations-js'; // Run `npm install --save web-animations-js`. @@ -58,9 +62,3 @@ import 'core-js/es7/reflect'; * Zone JS is required by default for Angular itself. */ import 'zone.js/dist/zone'; // Included with Angular CLI. - - - -/*************************************************************************************************** - * APPLICATION IMPORTS - */ diff --git a/src/styles.css b/src/styles.css @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/src/styles.scss b/src/styles.scss @@ -0,0 +1,2 @@ +/* You can add global styles to this file, and also import other style files */ +html { overflow:auto; } diff --git a/tsconfig.json b/tsconfig.json @@ -15,5 +15,6 @@ "es2017", "dom" ] - } + }, + "include": ["node_modules/angular-bootstrap-md/**/*.ts", "src/**/*.ts"] } diff --git a/tslint.json b/tslint.json @@ -30,7 +30,7 @@ "label-position": true, "max-line-length": [ true, - 140 + 280 ], "member-access": false, "member-ordering": [ diff --git a/yarn.lock b/yarn.lock @@ -11,6 +11,15 @@ typescript "~2.6.2" webpack-sources "^1.0.1" +"@angular-devkit/core@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.3.1.tgz#6aeb990dec92d06360597928748aeeedc21afdde" + dependencies: + ajv "~5.5.1" + chokidar "^1.7.0" + rxjs "^5.5.6" + source-map "^0.5.6" + "@angular-devkit/schematics@~0.0.42": version "0.0.52" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.0.52.tgz#cbd2f42778b50d6422a254ffaec05ad4ef3cb6c0" @@ -24,6 +33,12 @@ dependencies: tslib "^1.7.1" +"@angular/cdk@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-5.2.0.tgz#4368f6749e915cdcc75d325ae33fdb3f85a88108" + dependencies: + tslib "^1.7.1" + "@angular/cli@1.6.1": version "1.6.1" resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-1.6.1.tgz#6797995be1965bfc2e26234c728c9968cf7f3bdb" @@ -149,6 +164,12 @@ dependencies: tslib "^1.7.1" +"@angular/service-worker@^5.2.4": + version "5.2.4" + resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-5.2.4.tgz#23ef7366000908b22f5bb728435612c88400a1ff" + dependencies: + tslib "^1.7.1" + "@ngtools/json-schema@1.1.0", "@ngtools/json-schema@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.1.0.tgz#c3a0c544d62392acc2813a42c8a0dc6f58f86922" @@ -259,7 +280,7 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5: +ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@~5.5.1: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -284,6 +305,12 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +angular-bootstrap-md@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/angular-bootstrap-md/-/angular-bootstrap-md-5.1.2.tgz#bd9ef5c121ab9da52f34e8adfe12de9cf1edcb19" + dependencies: + moment "2.18.x" + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -879,6 +906,26 @@ chalk@~2.2.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chart.js@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.5.0.tgz#fe6e751a893769f56e72bee5ad91207e1c592957" + dependencies: + chartjs-color "^2.0.0" + moment "^2.10.6" + +chartjs-color-string@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz#8d3752d8581d86687c35bfe2cb80ac5213ceb8c1" + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.2.0.tgz#84a2fb755787ed85c39dd6dd8c7b1d88429baeae" + dependencies: + chartjs-color-string "^0.5.0" + color-convert "^0.5.3" + chokidar@^1.4.1, chokidar@^1.4.2, chokidar@^1.6.0, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -979,6 +1026,10 @@ codelyzer@^4.0.1: source-map "^0.5.6" sprintf-js "^1.0.3" +color-convert@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" + color-convert@^1.3.0, color-convert@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" @@ -2095,6 +2146,10 @@ flush-write-stream@^1.0.0: inherits "^2.0.1" readable-stream "^2.0.4" +font-awesome@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" + for-in@^0.1.3: version "0.1.8" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" @@ -2349,6 +2404,10 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +hammerjs@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" + handle-thing@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" @@ -3548,6 +3607,14 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkd dependencies: minimist "0.0.8" +moment@2.18.x: + version "2.18.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" + +moment@^2.10.6: + version "2.20.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -3596,6 +3663,10 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +ng-gallery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ng-gallery/-/ng-gallery-1.0.1.tgz#a3a90a91bb33b2d0f624d7e1ff12f2425a57b3ce" + no-case@^2.2.0: version "2.3.2" resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" @@ -5865,6 +5936,10 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.0" +web-animations-js@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/web-animations-js/-/web-animations-js-2.3.1.tgz#3a6d9bc15196377a90f8e2803fa5262165b04510" + webdriver-js-extender@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515"