Clean test of angular 7 migration.
No files matched your search
@@ -1,13 +0,0 @@
|
|||||||
# Editor configuration, see http://editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
max_line_length = off
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# compiled output
|
|
||||||
/dist
|
|
||||||
/tmp
|
|
||||||
/out-tsc
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
|
|
||||||
# IDEs and editors
|
|
||||||
/.idea
|
|
||||||
.project
|
|
||||||
.classpath
|
|
||||||
.c9/
|
|
||||||
*.launch
|
|
||||||
.settings/
|
|
||||||
*.sublime-workspace
|
|
||||||
|
|
||||||
# IDE - VSCode
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/.sass-cache
|
|
||||||
/connect.lock
|
|
||||||
/coverage
|
|
||||||
/libpeerconnection.log
|
|
||||||
npm-debug.log
|
|
||||||
yarn-error.log
|
|
||||||
testem.log
|
|
||||||
/typings
|
|
||||||
|
|
||||||
# System Files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
|
||||||
"version": 1,
|
|
||||||
"newProjectRoot": "projects",
|
|
||||||
"projects": {
|
|
||||||
"codiki": {
|
|
||||||
"root": "",
|
|
||||||
"sourceRoot": "src",
|
|
||||||
"projectType": "application",
|
|
||||||
"prefix": "app",
|
|
||||||
"schematics": {
|
|
||||||
"@schematics/angular:component": {
|
|
||||||
"styleext": "scss"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-angular:browser",
|
|
||||||
"options": {
|
|
||||||
"outputPath": "../resources/static/",
|
|
||||||
"index": "src/index.html",
|
|
||||||
"main": "src/main.ts",
|
|
||||||
"polyfills": "src/polyfills.ts",
|
|
||||||
"tsConfig": "src/tsconfig.app.json",
|
|
||||||
"assets": [
|
|
||||||
"src/favicon.ico",
|
|
||||||
"src/assets"
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"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",
|
|
||||||
"src/styles.scss"
|
|
||||||
],
|
|
||||||
"scripts": [
|
|
||||||
"node_modules/hammerjs/hammer.min.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.prod.ts"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"optimization": true,
|
|
||||||
"outputHashing": "all",
|
|
||||||
"sourceMap": false,
|
|
||||||
"extractCss": true,
|
|
||||||
"namedChunks": false,
|
|
||||||
"aot": true,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true
|
|
||||||
},
|
|
||||||
"integ": {
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.integ.ts"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"optimization": true,
|
|
||||||
"outputHashing": "all",
|
|
||||||
"sourceMap": true,
|
|
||||||
"extractCss": true,
|
|
||||||
"namedChunks": true,
|
|
||||||
"aot": true,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"vendorChunk": false,
|
|
||||||
"buildOptimizer": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"serve": {
|
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "codiki:build"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"browserTarget": "codiki:build:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extract-i18n": {
|
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "codiki:build"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"main": "src/test.ts",
|
|
||||||
"polyfills": "src/polyfills.ts",
|
|
||||||
"tsConfig": "src/tsconfig.spec.json",
|
|
||||||
"karmaConfig": "src/karma.conf.js",
|
|
||||||
"styles": [
|
|
||||||
"src/styles.css"
|
|
||||||
],
|
|
||||||
"scripts": [],
|
|
||||||
"assets": [
|
|
||||||
"src/favicon.ico",
|
|
||||||
"src/assets"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": [
|
|
||||||
"src/tsconfig.app.json",
|
|
||||||
"src/tsconfig.spec.json"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"codiki-e2e": {
|
|
||||||
"root": "e2e/",
|
|
||||||
"projectType": "application",
|
|
||||||
"architect": {
|
|
||||||
"e2e": {
|
|
||||||
"builder": "@angular-devkit/build-angular:protractor",
|
|
||||||
"options": {
|
|
||||||
"protractorConfig": "e2e/protractor.conf.js",
|
|
||||||
"devServerTarget": "codiki:serve"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"devServerTarget": "codiki:serve:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@angular-devkit/build-angular:tslint",
|
|
||||||
"options": {
|
|
||||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
|
||||||
"exclude": [
|
|
||||||
"**/node_modules/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultProject": "codiki"
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
// Protractor configuration file, see link for more information
|
|
||||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
|
||||||
|
|
||||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
|
||||||
|
|
||||||
exports.config = {
|
|
||||||
allScriptsTimeout: 11000,
|
|
||||||
specs: [
|
|
||||||
'./src/**/*.e2e-spec.ts'
|
|
||||||
],
|
|
||||||
capabilities: {
|
|
||||||
'browserName': 'chrome'
|
|
||||||
},
|
|
||||||
directConnect: true,
|
|
||||||
baseUrl: 'http://localhost:4200/',
|
|
||||||
framework: 'jasmine',
|
|
||||||
jasmineNodeOpts: {
|
|
||||||
showColors: true,
|
|
||||||
defaultTimeoutInterval: 30000,
|
|
||||||
print: function() {}
|
|
||||||
},
|
|
||||||
onPrepare() {
|
|
||||||
require('ts-node').register({
|
|
||||||
project: require('path').join(__dirname, './tsconfig.e2e.json')
|
|
||||||
});
|
|
||||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { AppPage } from './app.po';
|
|
||||||
|
|
||||||
describe('workspace-project App', () => {
|
|
||||||
let page: AppPage;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
page = new AppPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display welcome message', () => {
|
|
||||||
page.navigateTo();
|
|
||||||
expect(page.getParagraphText()).toEqual('Welcome to Codiki!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { browser, by, element } from 'protractor';
|
|
||||||
|
|
||||||
export class AppPage {
|
|
||||||
navigateTo() {
|
|
||||||
return browser.get('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
getParagraphText() {
|
|
||||||
return element(by.css('app-root h1')).getText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/app",
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es5",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"jasminewd2",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "codiki",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"scripts": {
|
|
||||||
"ng": "ng",
|
|
||||||
"start": "ng serve --proxy-config proxy.conf.json",
|
|
||||||
"build": "ng build",
|
|
||||||
"test": "ng test",
|
|
||||||
"lint": "ng lint",
|
|
||||||
"e2e": "ng e2e"
|
|
||||||
},
|
|
||||||
"private": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@angular/animations": "^7.2.1",
|
|
||||||
"@angular/common": "^7.2.1",
|
|
||||||
"@angular/compiler": "^7.2.1",
|
|
||||||
"@angular/core": "^7.2.1",
|
|
||||||
"@angular/forms": "^7.2.1",
|
|
||||||
"@angular/http": "^7.2.1",
|
|
||||||
"@angular/platform-browser": "^7.2.1",
|
|
||||||
"@angular/platform-browser-dynamic": "^7.2.1",
|
|
||||||
"@angular/router": "^7.2.1",
|
|
||||||
"angular-bootstrap-md": "^7.2.0",
|
|
||||||
"core-js": "^2.5.4",
|
|
||||||
"font-awesome": "^4.7.0",
|
|
||||||
"chart.js": "^2.5.0",
|
|
||||||
"hammerjs": "^2.0.8",
|
|
||||||
"rxjs": "~6.3.3",
|
|
||||||
"zone.js": "~0.8.28"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@angular-devkit/build-angular": "~0.8.0",
|
|
||||||
"@angular/cli": "^6.2.9",
|
|
||||||
"@angular/compiler-cli": "^7.2.1",
|
|
||||||
"@angular/language-service": "^7.2.1",
|
|
||||||
"@types/jasmine": "~2.8.8",
|
|
||||||
"@types/jasminewd2": "~2.0.3",
|
|
||||||
"@types/node": "~8.9.4",
|
|
||||||
"codelyzer": "~4.3.0",
|
|
||||||
"jasmine-core": "~2.99.1",
|
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
|
||||||
"karma": "~3.0.0",
|
|
||||||
"karma-chrome-launcher": "~2.2.0",
|
|
||||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
|
||||||
"karma-jasmine": "~1.1.2",
|
|
||||||
"karma-jasmine-html-reporter": "^0.2.2",
|
|
||||||
"protractor": "~5.4.0",
|
|
||||||
"ts-node": "~7.0.0",
|
|
||||||
"tslint": "~5.11.0",
|
|
||||||
"typescript": "~3.2.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<h1>Paramètres</h1>
|
|
||||||
<div class="align-top">
|
|
||||||
<div class="card hoverable">
|
|
||||||
<a routerLink="/changePassword">
|
|
||||||
<div class="card-body row">
|
|
||||||
<div class="col-10">
|
|
||||||
<h4>
|
|
||||||
<i class="fa fa-lock blue-text"></i>
|
|
||||||
Mot de passe
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div class="col-1 d-flex align-items-center text-right">
|
|
||||||
<i class="fa fa-chevron-right"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body grey lighten-4">
|
|
||||||
Changer de mot de passe
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="card hoverable">
|
|
||||||
<a routerLink="/profilEdit">
|
|
||||||
<div class="card-body row">
|
|
||||||
<div class="col-10">
|
|
||||||
<h4>
|
|
||||||
<i class="fa fa-user-circle blue-text"></i>
|
|
||||||
Mes informations
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div class="col-1 d-flex align-items-center text-right">
|
|
||||||
<i class="fa fa-chevron-right"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body grey lighten-4">
|
|
||||||
Modifier les informations personnelles comme mon nom, mon adresse mail ou encore mon image de profil
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="card grey-text">
|
|
||||||
<div class="card-body row">
|
|
||||||
<div class="col-10">
|
|
||||||
<h4>
|
|
||||||
<i class="fa fa-cog"></i>
|
|
||||||
Paramètres de compte
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div class="col-1 d-flex align-items-center text-right">
|
|
||||||
<i class="fa fa-chevron-right"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body grey lighten-4">
|
|
||||||
Paramètres divers
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-account-settings',
|
|
||||||
templateUrl: './account-settings.component.html',
|
|
||||||
styles: [`
|
|
||||||
h4 i {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
a, a:visited, a:hover {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
margin-right: 20px;
|
|
||||||
width: 30%;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class AccountSettingsComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
<div class="card col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
|
||||||
<div id="form" class="card-body">
|
|
||||||
<h4 class="card-title">Mot de passe</h4>
|
|
||||||
<form (ngSubmit)="onSubmit()" #changePasswordForm="ngForm">
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="oldPassword"
|
|
||||||
name="oldPassword"
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.oldPassword"
|
|
||||||
#oldPassword="ngModel"
|
|
||||||
data-error="Veuillez saisir votre mot de passe actuel"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="oldPassword">Mot de passe actuel</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="newPassword"
|
|
||||||
name="newPassword"
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.newPassword"
|
|
||||||
#newPassword="ngModel"
|
|
||||||
data-error="Veuillez saisir votre nouveau mot de passe"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="newPassword">Nouveau mot de passe</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="confirmPassword"
|
|
||||||
name="confirmPassword"
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.confirmPassword"
|
|
||||||
#confirmPassword="ngModel"
|
|
||||||
data-error="Veuillez confirmer votre nouveau mot de passe"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="confirmPassword">Confirmation de votre mot de passe</label>
|
|
||||||
</div>
|
|
||||||
<div class="card red lighten-2 text-center z-depth-2" *ngIf="error">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{error}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col submitFormArea">
|
|
||||||
<a routerLink="/accountSettings" class="indigo-text">
|
|
||||||
Annuler
|
|
||||||
</a>
|
|
||||||
<button class="float-right waves-effect waves-light indigo btn"
|
|
||||||
type="submit" [disabled]="!changePasswordForm.form.valid">
|
|
||||||
Suivant
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { PasswordWrapper } from '../../core/entities';
|
|
||||||
import { ChangePasswordService } from './change-password.service';
|
|
||||||
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-change-password',
|
|
||||||
templateUrl: './change-password.component.html',
|
|
||||||
styles: [`
|
|
||||||
#form.card-body {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submitFormArea {
|
|
||||||
line-height: 50px;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class ChangePasswordComponent {
|
|
||||||
model: PasswordWrapper = new PasswordWrapper('', '', '');
|
|
||||||
|
|
||||||
error: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private changePasswordService: ChangePasswordService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
onSubmit(): void {
|
|
||||||
if (this.model.newPassword !== this.model.confirmPassword) {
|
|
||||||
this.error = 'Les mots de passe saisis ne correspondent pas.';
|
|
||||||
} else {
|
|
||||||
this.changePasswordService.changePassword(this.model).subscribe(null, error => {
|
|
||||||
this.error = 'Le mot de passe saisi ne correspond pas au votre.';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { PasswordWrapper } from '../../core/entities';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const ACCOUNT_URL = environment.apiUrl + '/api/account';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ChangePasswordService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
changePassword(passwordWrapper: PasswordWrapper): Observable<any> {
|
|
||||||
return this.http.put(ACCOUNT_URL + '/changePassword', passwordWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
<input id="profilImageInput" type="file" (change)="uploadImage($event)" [hidden]="true">
|
|
||||||
<div class="col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
|
||||||
<div class="card">
|
|
||||||
<img id="profil-image" class="card-img-top"
|
|
||||||
(click)="triggerProfilImageChange()"
|
|
||||||
[src]="getAvatarUrl()"
|
|
||||||
alt="Card image cap"
|
|
||||||
mdbTooltip="Modifier mon image de profil"
|
|
||||||
placement="bottom">
|
|
||||||
<div id="form" class="card-body">
|
|
||||||
<form (ngSubmit)="onSubmit()" #profilEditionForm="ngForm">
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="name"
|
|
||||||
name="name"
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.name"
|
|
||||||
#name="ngModel"
|
|
||||||
data-error="Veuillez saisir votre nom d'utilisateur"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="name">Nom d'utilisateur</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.email"
|
|
||||||
#email="ngModel"
|
|
||||||
data-error="Veuillez saisir votre adresse email"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="email">Email</label>
|
|
||||||
</div>
|
|
||||||
<div id="errorMsg" class="card red lighten-2 text-center z-depth-2">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{modelError}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="resultMsg" class="card green lighten-2 text-center z-depth-2" >
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{result}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col submitFormArea">
|
|
||||||
<a routerLink="/accountSettings" class="indigo-text">
|
|
||||||
Annuler
|
|
||||||
</a>
|
|
||||||
<button class="float-right waves-effect waves-light indigo btn"
|
|
||||||
type="submit" [disabled]="!profilEditionForm.form.valid">
|
|
||||||
Suivant
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { ProfilEditionService } from './profil-edition.service';
|
|
||||||
import { HttpEventType, HttpResponse } from '@angular/common/http';
|
|
||||||
import { User } from '../../core/entities';
|
|
||||||
import { AuthService } from '../../core/services/auth.service';
|
|
||||||
import { environment } from '../../../environments/environment';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-profil-edition',
|
|
||||||
templateUrl: './profil-edition.component.html',
|
|
||||||
styles: [`
|
|
||||||
#form {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submitFormArea {
|
|
||||||
line-height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#profil-image {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#resultMsg, #errorMsg {
|
|
||||||
max-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.5s ease-out;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class ProfilEditionComponent implements OnInit {
|
|
||||||
model: User;
|
|
||||||
selectedFiles: FileList;
|
|
||||||
currentFileUpload: File;
|
|
||||||
progress: { percentage: number } = { percentage: 0 };
|
|
||||||
modelError: string;
|
|
||||||
result: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private profilEditionService: ProfilEditionService,
|
|
||||||
private authService: AuthService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.model = this.authService.getUser();
|
|
||||||
}
|
|
||||||
|
|
||||||
getAvatarUrl(): string {
|
|
||||||
return this.model.image
|
|
||||||
? `${environment.apiUrl}/api/images/loadAvatar/${this.model.image}`
|
|
||||||
: './assets/images/default_user.png';
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerProfilImageChange(): void {
|
|
||||||
document.getElementById('profilImageInput').click();
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadImage(event) {
|
|
||||||
this.selectedFiles = event.target.files;
|
|
||||||
this.progress.percentage = 0;
|
|
||||||
|
|
||||||
this.currentFileUpload = this.selectedFiles.item(0);
|
|
||||||
// This prevents error 400 if user doesn't select any file to upload and close the input file.
|
|
||||||
if (this.currentFileUpload) {
|
|
||||||
this.profilEditionService.uploadAvatarPicture(this.currentFileUpload).subscribe(result => {
|
|
||||||
if (result.type === HttpEventType.UploadProgress) {
|
|
||||||
this.progress.percentage = Math.round(100 * result.loaded / result.total);
|
|
||||||
} else if (result instanceof HttpResponse) {
|
|
||||||
console.log('File ' + result.body + ' completely uploaded!');
|
|
||||||
this.model.image = result.body as string;
|
|
||||||
this.authService.setUser(this.model);
|
|
||||||
}
|
|
||||||
this.selectedFiles = undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(): void {
|
|
||||||
this.profilEditionService.updateUser(this.model).subscribe(() => {
|
|
||||||
this.setMessage('Modification enregistrée.', false);
|
|
||||||
}, error => {
|
|
||||||
this.setMessage('L\'adresse mail saisie n\'est pas disponible.', true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setMessage(message: string, error: boolean): void {
|
|
||||||
this[error ? 'modelError' : 'result'] = message;
|
|
||||||
|
|
||||||
const resultMsgDiv = document.getElementById(error ? 'errorMsg' : 'resultMsg');
|
|
||||||
resultMsgDiv.style.maxHeight = '64px';
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
resultMsgDiv.style.maxHeight = '0px';
|
|
||||||
setTimeout(() => {
|
|
||||||
this[error ? 'modelError' : 'result'] = undefined;
|
|
||||||
}, 550);
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import {HttpClient, HttpRequest, HttpEvent} from '@angular/common/http';
|
|
||||||
import {Observable} from 'rxjs';
|
|
||||||
import { User } from '../../core/entities';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const IMAGES_URL = environment.apiUrl + '/api/images';
|
|
||||||
const ACCOUNT_URL = environment.apiUrl + '/api/account';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ProfilEditionService {
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
uploadAvatarPicture(file: File): Observable<HttpEvent<{}>> {
|
|
||||||
const formData: FormData = new FormData();
|
|
||||||
|
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
return this.http.request(new HttpRequest(
|
|
||||||
'POST', IMAGES_URL + '/uploadAvatar', formData, {
|
|
||||||
reportProgress: true,
|
|
||||||
responseType: 'text'
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
updateUser(user: User): Observable<any> {
|
|
||||||
return this.http.put<any>(`${ACCOUNT_URL}/`, user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<app-header></app-header>
|
|
||||||
<main class="container">
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</main>
|
|
||||||
<app-footer></app-footer>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import { TestBed, async } from '@angular/core/testing';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
describe('AppComponent', () => {
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [
|
|
||||||
AppComponent
|
|
||||||
],
|
|
||||||
}).compileComponents();
|
|
||||||
}));
|
|
||||||
it('should create the app', async(() => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app).toBeTruthy();
|
|
||||||
}));
|
|
||||||
it(`should have as title 'Codiki'`, async(() => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
const app = fixture.debugElement.componentInstance;
|
|
||||||
expect(app.title).toEqual('Codiki');
|
|
||||||
}));
|
|
||||||
it('should render title in a h1 tag', async(() => {
|
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
|
||||||
fixture.detectChanges();
|
|
||||||
const compiled = fixture.debugElement.nativeElement;
|
|
||||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to Codiki!');
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-root',
|
|
||||||
templateUrl: './app.component.html',
|
|
||||||
styleUrls: ['./app.component.css']
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
title = 'codiki';
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
// Angular core
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
|
|
||||||
import { FormsModule } from '@angular/forms';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
||||||
|
|
||||||
// Dependencies
|
|
||||||
import { MDBBootstrapModule } from 'angular-bootstrap-md';
|
|
||||||
|
|
||||||
// Router
|
|
||||||
import { appRoutes } from './app.routes';
|
|
||||||
|
|
||||||
// Components
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
import { HeaderComponent } from './header/header.component';
|
|
||||||
import { FooterComponent } from './footer/footer.component';
|
|
||||||
import { NotFoundComponent } from './not-found/not-found.component';
|
|
||||||
import { HomeComponent } from './home/home.component';
|
|
||||||
import { LoginComponent } from './login/login.component';
|
|
||||||
import { DisconnectionComponent } from './disconnection/disconnection.component';
|
|
||||||
import { PostCardComponent } from './core/post-card/post-card.component';
|
|
||||||
import { PostComponent } from './posts/post.component';
|
|
||||||
import { ByCategoryComponent } from './posts/byCategory/by-category.component';
|
|
||||||
import { MyPostsComponent } from './posts/myPosts/my-posts.component';
|
|
||||||
import { AccountSettingsComponent } from './account-settings/account-settings.component';
|
|
||||||
import { ChangePasswordComponent } from './account-settings/change-password/change-password.component';
|
|
||||||
import { ProfilEditionComponent } from './account-settings/profil-edition/profil-edition.component';
|
|
||||||
import { CreateUpdatePostComponent } from './posts/create-update/create-update-post.component';
|
|
||||||
import { ForbiddenComponent } from './forbidden/forbidden.component';
|
|
||||||
import { SearchComponent } from './search/search.component';
|
|
||||||
import { SigninComponent } from './signin/signin.component';
|
|
||||||
import { VersionRevisionComponent } from './version-revisions/version-revisions.component';
|
|
||||||
|
|
||||||
// html components
|
|
||||||
import { ProgressBarComponent } from './core/directives/progress-bar/progress-bar.component';
|
|
||||||
import { SpinnerComponent } from './core/directives/spinner/spinner.component';
|
|
||||||
import { SearchBarComponent } from './core/directives/search-bar/search-bar.component';
|
|
||||||
|
|
||||||
// Services
|
|
||||||
import { AuthService } from './core/services/auth.service';
|
|
||||||
import { LoginService } from './login/login.service';
|
|
||||||
import { HomeService } from './home/home.service';
|
|
||||||
import { PostService } from './posts/post.service';
|
|
||||||
import { ByCategoryService } from './posts/byCategory/by-category.service';
|
|
||||||
import { MyPostsService } from './posts/myPosts/my-posts.service';
|
|
||||||
import { ChangePasswordService } from './account-settings/change-password/change-password.service';
|
|
||||||
import { ProfilEditionService } from './account-settings/profil-edition/profil-edition.service';
|
|
||||||
import { HeaderService } from './header/header.service';
|
|
||||||
import { CreateUpdatePostService } from './posts/create-update/create-update-post.service';
|
|
||||||
import { SearchService } from './search/search.service';
|
|
||||||
import { VersionRevisionService } from './version-revisions/version-revisions.service';
|
|
||||||
|
|
||||||
// Guards
|
|
||||||
import { AuthGuard } from './core/guards/auth.guard';
|
|
||||||
|
|
||||||
// Interceptors
|
|
||||||
import { TokenInterceptor } from './core/interceptors/token-interceptor';
|
|
||||||
import { SigninService } from './signin/signin.service';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
AppComponent,
|
|
||||||
HeaderComponent,
|
|
||||||
FooterComponent,
|
|
||||||
NotFoundComponent,
|
|
||||||
HomeComponent,
|
|
||||||
LoginComponent,
|
|
||||||
DisconnectionComponent,
|
|
||||||
PostCardComponent,
|
|
||||||
PostComponent,
|
|
||||||
ByCategoryComponent,
|
|
||||||
MyPostsComponent,
|
|
||||||
AccountSettingsComponent,
|
|
||||||
CreateUpdatePostComponent,
|
|
||||||
ChangePasswordComponent,
|
|
||||||
ProfilEditionComponent,
|
|
||||||
ForbiddenComponent,
|
|
||||||
SearchComponent,
|
|
||||||
SigninComponent,
|
|
||||||
ProgressBarComponent,
|
|
||||||
SpinnerComponent,
|
|
||||||
SearchBarComponent,
|
|
||||||
VersionRevisionComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
HttpClientModule,
|
|
||||||
FormsModule,
|
|
||||||
MDBBootstrapModule.forRoot(),
|
|
||||||
RouterModule.forRoot(
|
|
||||||
appRoutes,
|
|
||||||
// { enableTracing: true } // Enabling tracing
|
|
||||||
{ onSameUrlNavigation: 'reload' }
|
|
||||||
)
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
AuthService,
|
|
||||||
LoginService,
|
|
||||||
SigninService,
|
|
||||||
HomeService,
|
|
||||||
PostService,
|
|
||||||
ByCategoryService,
|
|
||||||
MyPostsService,
|
|
||||||
ChangePasswordService,
|
|
||||||
ProfilEditionService,
|
|
||||||
HeaderService,
|
|
||||||
CreateUpdatePostService,
|
|
||||||
SearchService,
|
|
||||||
VersionRevisionService,
|
|
||||||
// AuthGuard,
|
|
||||||
// {
|
|
||||||
// provide: HTTP_INTERCEPTORS,
|
|
||||||
// useClass: TokenInterceptor,
|
|
||||||
// multi: true
|
|
||||||
// }
|
|
||||||
],
|
|
||||||
bootstrap: [AppComponent]
|
|
||||||
})
|
|
||||||
export class AppModule { }
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import { Routes } from '@angular/router';
|
|
||||||
|
|
||||||
import { HomeComponent } from './home/home.component';
|
|
||||||
import { NotFoundComponent } from './not-found/not-found.component';
|
|
||||||
import { LoginComponent } from './login/login.component';
|
|
||||||
import { SigninComponent } from './signin/signin.component';
|
|
||||||
import { DisconnectionComponent } from './disconnection/disconnection.component';
|
|
||||||
import { PostComponent } from './posts/post.component';
|
|
||||||
import { ByCategoryComponent } from './posts/byCategory/by-category.component';
|
|
||||||
import { MyPostsComponent } from './posts/myPosts/my-posts.component';
|
|
||||||
import { AccountSettingsComponent } from './account-settings/account-settings.component';
|
|
||||||
import { ChangePasswordComponent } from './account-settings/change-password/change-password.component';
|
|
||||||
import { CreateUpdatePostComponent } from './posts/create-update/create-update-post.component';
|
|
||||||
import { ForbiddenComponent } from './forbidden/forbidden.component';
|
|
||||||
import { ProfilEditionComponent } from './account-settings/profil-edition/profil-edition.component';
|
|
||||||
import { SearchComponent } from './search/search.component';
|
|
||||||
import { VersionRevisionComponent } from './version-revisions/version-revisions.component';
|
|
||||||
|
|
||||||
import { AuthGuard } from './core/guards/auth.guard';
|
|
||||||
|
|
||||||
// export const appRoutes: Routes = [
|
|
||||||
// { path: 'login', component: LoginComponent },
|
|
||||||
// { path: 'signin', component: SigninComponent },
|
|
||||||
// { path: 'home', component: HomeComponent },
|
|
||||||
// { path: 'disconnection', component: DisconnectionComponent },
|
|
||||||
// { path: 'posts/new', component: CreateUpdatePostComponent, canActivate: [AuthGuard] },
|
|
||||||
// { path: 'posts/update/:postKey', component: CreateUpdatePostComponent, canActivate: [AuthGuard] },
|
|
||||||
// { path: 'posts/:postKey', component: PostComponent },
|
|
||||||
// { path: 'posts/byCategory/:categoryId', component: ByCategoryComponent},
|
|
||||||
// { path: 'posts/search/:searchCriteria', component: SearchComponent},
|
|
||||||
// { path: 'myPosts', component: MyPostsComponent, canActivate: [AuthGuard]},
|
|
||||||
// { path: 'accountSettings', component: AccountSettingsComponent, canActivate: [AuthGuard] },
|
|
||||||
// { path: 'changePassword', component: ChangePasswordComponent, canActivate: [AuthGuard] },
|
|
||||||
// { path: 'profilEdit', component: ProfilEditionComponent, canActivate: [AuthGuard] },
|
|
||||||
// { path: 'versionrevisions', component: VersionRevisionComponent },
|
|
||||||
// { path: 'forbidden', component: ForbiddenComponent },
|
|
||||||
// { path: '', redirectTo: '/home', pathMatch: 'full' },
|
|
||||||
// { path: '**', component: NotFoundComponent }
|
|
||||||
// ];
|
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
|
||||||
{ path: 'login', component: LoginComponent },
|
|
||||||
{ path: 'signin', component: SigninComponent },
|
|
||||||
{ path: 'home', component: HomeComponent },
|
|
||||||
{ path: 'disconnection', component: DisconnectionComponent },
|
|
||||||
{ path: 'posts/new', component: CreateUpdatePostComponent },
|
|
||||||
{ path: 'posts/update/:postKey', component: CreateUpdatePostComponent },
|
|
||||||
{ path: 'posts/:postKey', component: PostComponent },
|
|
||||||
{ path: 'posts/byCategory/:categoryId', component: ByCategoryComponent},
|
|
||||||
{ path: 'posts/search/:searchCriteria', component: SearchComponent},
|
|
||||||
{ path: 'myPosts', component: MyPostsComponent},
|
|
||||||
{ path: 'accountSettings', component: AccountSettingsComponent },
|
|
||||||
{ path: 'changePassword', component: ChangePasswordComponent },
|
|
||||||
{ path: 'profilEdit', component: ProfilEditionComponent },
|
|
||||||
{ path: 'versionrevisions', component: VersionRevisionComponent },
|
|
||||||
{ path: 'forbidden', component: ForbiddenComponent },
|
|
||||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
|
||||||
{ path: '**', component: NotFoundComponent }
|
|
||||||
];
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
.progress {
|
|
||||||
position: relative;
|
|
||||||
height: 4px;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
background-color: #3F729B;
|
|
||||||
border-radius: 2px;
|
|
||||||
background-clip: padding-box;
|
|
||||||
margin: 0.5rem 0 1rem 0;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-animation: random-background 5s infinite;
|
|
||||||
animation: random-background 5s infinite;transition: all 0.3s ease-out;
|
|
||||||
}
|
|
||||||
@keyframes random-background {
|
|
||||||
15% { background-color: #ff444480; }
|
|
||||||
30% { background-color: #ffbb3381; }
|
|
||||||
45% { background-color: rgba(0, 200, 80, 0.575); }
|
|
||||||
60% { background-color: #33b6e58c; }
|
|
||||||
75% { background-color: #aa66cc7c; }
|
|
||||||
}
|
|
||||||
.progress .indeterminate {
|
|
||||||
background-color: #1C2331;
|
|
||||||
-webkit-animation: random-bar 5s infinite;
|
|
||||||
animation: random-bar 5s infinite;transition: all 0.3s ease-out;
|
|
||||||
}
|
|
||||||
@keyframes random-bar {
|
|
||||||
15% { background-color: #ff4444; }
|
|
||||||
30% { background-color: #ffbb33; }
|
|
||||||
45% { background-color: #00C851; }
|
|
||||||
60% { background-color: #33b5e5; }
|
|
||||||
75% { background-color: #aa66cc; }
|
|
||||||
}
|
|
||||||
.progress .indeterminate:before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
background-color: inherit;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
will-change: left, right;
|
|
||||||
-webkit-animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
|
|
||||||
animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
|
|
||||||
}
|
|
||||||
.progress .indeterminate:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
background-color: inherit;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
will-change: left, right;
|
|
||||||
-webkit-animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
|
|
||||||
animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
|
|
||||||
-webkit-animation-delay: 1.15s;
|
|
||||||
animation-delay: 1.15s;
|
|
||||||
}
|
|
||||||
@-webkit-keyframes indeterminate {
|
|
||||||
0% {
|
|
||||||
left: -35%;
|
|
||||||
right: 100%;
|
|
||||||
}
|
|
||||||
60% {
|
|
||||||
left: 100%;
|
|
||||||
right: -90%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 100%;
|
|
||||||
right: -90%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes indeterminate {
|
|
||||||
0% {
|
|
||||||
left: -35%;
|
|
||||||
right: 100%;
|
|
||||||
}
|
|
||||||
60% {
|
|
||||||
left: 100%;
|
|
||||||
right: -90%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 100%;
|
|
||||||
right: -90%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@-webkit-keyframes indeterminate-short {
|
|
||||||
0% {
|
|
||||||
left: -200%;
|
|
||||||
right: 100%;
|
|
||||||
}
|
|
||||||
60% {
|
|
||||||
left: 107%;
|
|
||||||
right: -8%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 107%;
|
|
||||||
right: -8%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes indeterminate-short {
|
|
||||||
0% {
|
|
||||||
left: -200%;
|
|
||||||
right: 100%;
|
|
||||||
}
|
|
||||||
60% {
|
|
||||||
left: 107%;
|
|
||||||
right: -8%;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
left: 107%;
|
|
||||||
right: -8%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-progress-bar',
|
|
||||||
template: `
|
|
||||||
<div class="progress">
|
|
||||||
<div class="indeterminate"></div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styleUrls: ['./progress-bar.component.scss']
|
|
||||||
})
|
|
||||||
export class ProgressBarComponent {}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-search-bar',
|
|
||||||
template: `
|
|
||||||
<div id="search-bar">
|
|
||||||
<input id="search" name="search" type="text" [(ngModel)]="model" (keyup.enter)="search()" />
|
|
||||||
<label for="search" class="label-icon">
|
|
||||||
<i id="search-icon" class="fa fa-search" (click)="search()"></i>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: [`
|
|
||||||
div#search-bar {
|
|
||||||
position: relative;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#search, input#search:focus {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#search {
|
|
||||||
width: 400px;
|
|
||||||
height: 36px;
|
|
||||||
color: white;
|
|
||||||
background-color: #5c6bc0;
|
|
||||||
border-radius: 2px;
|
|
||||||
border-style: unset;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input#search:focus {
|
|
||||||
background: white;
|
|
||||||
color: #3f51b5;
|
|
||||||
}
|
|
||||||
|
|
||||||
i#search-icon {
|
|
||||||
font-size: 20px;
|
|
||||||
position: absolute;
|
|
||||||
right: 15px;
|
|
||||||
top: 8px;
|
|
||||||
color: #9e9e9e;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class SearchBarComponent {
|
|
||||||
model: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
search(): void {
|
|
||||||
if (this.model) {
|
|
||||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
|
||||||
this.router.navigateByUrl(`/posts/search/${this.model}`).then(() => {
|
|
||||||
this.router.navigated = false;
|
|
||||||
this.router.navigate([this.router.url]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
$green: #00C851;
|
|
||||||
$blue: #33b5e5;
|
|
||||||
$red: #ff4444;
|
|
||||||
$yellow: #ffbb33;
|
|
||||||
$white: #eee;
|
|
||||||
|
|
||||||
$width: 100px;
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: $white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.showbox {
|
|
||||||
padding: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
position: relative;
|
|
||||||
margin: 0 auto;
|
|
||||||
width: $width;
|
|
||||||
&:before {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
padding-top: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.circular {
|
|
||||||
animation: rotate 2s linear infinite;
|
|
||||||
height: 100%;
|
|
||||||
transform-origin: center center;
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.path {
|
|
||||||
stroke-dasharray: 1, 200;
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;
|
|
||||||
stroke-linecap: round;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotate {
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes dash {
|
|
||||||
0% {
|
|
||||||
stroke-dasharray: 1, 200;
|
|
||||||
stroke-dashoffset: 0;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
stroke-dasharray: 89, 200;
|
|
||||||
stroke-dashoffset: -35px;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
stroke-dasharray: 89, 200;
|
|
||||||
stroke-dashoffset: -124px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes color {
|
|
||||||
100%,
|
|
||||||
0% {
|
|
||||||
stroke: $red;
|
|
||||||
}
|
|
||||||
40% {
|
|
||||||
stroke: $blue;
|
|
||||||
}
|
|
||||||
66% {
|
|
||||||
stroke: $green;
|
|
||||||
}
|
|
||||||
80%,
|
|
||||||
90% {
|
|
||||||
stroke: $yellow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-spinner',
|
|
||||||
template: `
|
|
||||||
<div class="showbox">
|
|
||||||
<div class="loader">
|
|
||||||
<svg class="circular" viewBox="25 25 50 50">
|
|
||||||
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styleUrls: ['./spinner.component.scss']
|
|
||||||
})
|
|
||||||
export class SpinnerComponent {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
export class Role {
|
|
||||||
constructor(
|
|
||||||
public id: number,
|
|
||||||
public name: string
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class User {
|
|
||||||
constructor(
|
|
||||||
public key: string,
|
|
||||||
public name: string,
|
|
||||||
public email: string,
|
|
||||||
public password: string,
|
|
||||||
public image: string,
|
|
||||||
public inscriptionDate: Date,
|
|
||||||
public role: Role,
|
|
||||||
public token: string
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Post {
|
|
||||||
constructor(
|
|
||||||
public key: string,
|
|
||||||
public title: string,
|
|
||||||
public text: string,
|
|
||||||
public description: string,
|
|
||||||
public image: string,
|
|
||||||
public creationDate: Date,
|
|
||||||
public author: User,
|
|
||||||
public category: Category
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Category {
|
|
||||||
constructor(
|
|
||||||
public id: number,
|
|
||||||
public name: string,
|
|
||||||
public listSubCategories: Array<Category>
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Image {
|
|
||||||
constructor(
|
|
||||||
public id: number,
|
|
||||||
public link: string
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to send the new password to backoffice in order to change the user password.
|
|
||||||
*/
|
|
||||||
export class PasswordWrapper {
|
|
||||||
constructor(
|
|
||||||
public oldPassword: string,
|
|
||||||
public newPassword: string,
|
|
||||||
public confirmPassword: string
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Version {
|
|
||||||
constructor(
|
|
||||||
public id: number,
|
|
||||||
public number: string,
|
|
||||||
public active: boolean
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VersionRevision {
|
|
||||||
constructor(
|
|
||||||
public id: number,
|
|
||||||
public text: string,
|
|
||||||
public version: Version,
|
|
||||||
public bugfix: boolean
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
|
||||||
|
|
||||||
import { AuthService } from '../services/auth.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AuthGuard implements CanActivate {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private authService: AuthService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
|
||||||
let result: boolean;
|
|
||||||
|
|
||||||
if (this.authService.isAuthenticated()) {
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
this.router.navigate(['/login']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
import { User } from '../entities';
|
|
||||||
import { AuthService } from '../services/auth.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class TokenInterceptor implements HttpInterceptor {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private authService: AuthService,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
|
||||||
const token = this.authService.getToken();
|
|
||||||
|
|
||||||
let request: HttpRequest<any> = req;
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
request = req.clone({
|
|
||||||
setHeaders: {
|
|
||||||
token: token
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
// return next.handle(request).tap((event: HttpEvent<any>) => {
|
|
||||||
// // Do nothing for the interceptor
|
|
||||||
// }, (err: any) => {
|
|
||||||
// if (err instanceof HttpErrorResponse && err.status === 401) {
|
|
||||||
// this.authService.disconnect();
|
|
||||||
// this.router.navigate(['/login']);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
|
||||||
import { Post } from '../entities';
|
|
||||||
import { environment } from '../../../environments/environment';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-post-card',
|
|
||||||
template: `
|
|
||||||
<div class="card hoverable">
|
|
||||||
<div class="view hm-white-slight waves-light" mdbRippleRadius>
|
|
||||||
<img id="post-image" class="img-fluid" [src]="post.image" alt="Article" />
|
|
||||||
<a routerLink="/posts/{{post.key}}">
|
|
||||||
<div class="mask"></div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<h4 class="card-title">{{post.title}}</h4>
|
|
||||||
<p class="card-text">{{post.description}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="card-data">
|
|
||||||
<img [src]="getAvatarUrl()"
|
|
||||||
class="author-img"
|
|
||||||
[alt]="post.author.name"
|
|
||||||
[mdbTooltip]="post.author.name"
|
|
||||||
placement="bottom"/>
|
|
||||||
Article écrit par {{post.author.name}}
|
|
||||||
<span class="creation-date-area">({{post.creationDate | date:'yyyy-MM-dd HH:mm:ss'}})</span>
|
|
||||||
</div>
|
|
||||||
</div>`,
|
|
||||||
styles: [`
|
|
||||||
div.card {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
.card .card-data {
|
|
||||||
padding: 15px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
.creation-date-area {
|
|
||||||
color: #bdbdbd;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.author-img {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
#post-image {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class PostCardComponent {
|
|
||||||
@Input() post: Post;
|
|
||||||
|
|
||||||
getAvatarUrl(): string {
|
|
||||||
return this.post.author.image
|
|
||||||
? `${environment.apiUrl}/api/images/loadAvatar/${this.post.author.image}`
|
|
||||||
: './assets/images/default_user.png';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { User } from '../entities';
|
|
||||||
|
|
||||||
const PARAM_TOKEN = 'token';
|
|
||||||
const PARAM_USER = 'user';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AuthService {
|
|
||||||
authenticated: boolean = false;
|
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
public setAuthenticated(pAuthenticated: boolean): void {
|
|
||||||
this.authenticated = pAuthenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getToken(): string {
|
|
||||||
return localStorage.getItem(PARAM_TOKEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public setToken(token: string): void {
|
|
||||||
localStorage.setItem(PARAM_TOKEN, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
public isAuthenticated(): boolean {
|
|
||||||
return this.authenticated;
|
|
||||||
}
|
|
||||||
|
|
||||||
public disconnect(): void {
|
|
||||||
localStorage.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public isAdmin(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setUser(user: User): void {
|
|
||||||
localStorage.setItem(PARAM_USER, JSON.stringify(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public getUser(): User {
|
|
||||||
return JSON.parse(localStorage.getItem(PARAM_USER));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
import { AuthService } from '../core/services/auth.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-disconnection',
|
|
||||||
template: 'Déconnexion...'
|
|
||||||
})
|
|
||||||
export class DisconnectionComponent implements OnInit {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private authService: AuthService,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.authService.setAuthenticated(false);
|
|
||||||
this.router.navigate(['/home']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<footer class="page-footer indigo center-on-small-only">
|
|
||||||
<!-- fixed-bottom -->
|
|
||||||
<div class="footer-copyright">
|
|
||||||
<div class="container">
|
|
||||||
<span class="float-left">
|
|
||||||
<span class="anticopy">©</span> 2017 Tous droits réservés -
|
|
||||||
<i id="appVersion" routerLink="/versionrevisions" mdbTooltip="Notes de versions" placement="top" mdbRippleRadius>
|
|
||||||
{{appVersion}}
|
|
||||||
</i>
|
|
||||||
</span>
|
|
||||||
<span class="float-right">
|
|
||||||
<a target="_blank" href="./assets/doc/codiki_user_manual.pdf" mdbTooltip="Manuel d'utilisation" placement="top" mdbRippleRadius>
|
|
||||||
<i class="fa fa-book"></i>
|
|
||||||
</a> -
|
|
||||||
Développements réalisés par
|
|
||||||
<a href="mailto:florian.thierry72@gmail.com">Florian THIERRY</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
footer {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-footer {
|
|
||||||
padding-top: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.anticopy {
|
|
||||||
display: inline-block;
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#appVersion {
|
|
||||||
color: rgba(255, 255, 255, 0.6);
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-footer',
|
|
||||||
templateUrl: './footer.component.html',
|
|
||||||
styleUrls: ['./footer.component.scss']
|
|
||||||
})
|
|
||||||
export class FooterComponent {
|
|
||||||
appVersion = environment.appVersion;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-forbidden',
|
|
||||||
template: `
|
|
||||||
<div class="text-center">
|
|
||||||
<img src="./assets/images/403.png" alt="403" />
|
|
||||||
<h3>Vous n'êtes pas autorisé à effectuer cette action...</h3>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styles: [`
|
|
||||||
img {
|
|
||||||
max-height: 500px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class ForbiddenComponent {}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
<mdb-navbar SideClass="navbar fixed-top navbar-expand-lg navbar-dark indigo scrolling-navbar ie-nav" [containerInside]="false">
|
|
||||||
<logo>
|
|
||||||
<a class="logo navbar-brand" routerLink="/">
|
|
||||||
<img id="logo" src="./assets/images/codiki.png" alt="logo" />
|
|
||||||
<span id="title" *ngIf="!title">Codiki</span>
|
|
||||||
<span id="title" *ngIf="title">Codiki - {{title}}</span>
|
|
||||||
</a>
|
|
||||||
</logo>
|
|
||||||
<links>
|
|
||||||
<div class="navbar-nav ml-auto nav-flex-icons">
|
|
||||||
<app-search-bar></app-search-bar>
|
|
||||||
</div>
|
|
||||||
<ul class="navbar-nav ml-auto nav-flex-icons" style="margin-left: 0 !important;">
|
|
||||||
<li class="nav-item" *ngIf="!isAuthenticated()">
|
|
||||||
<a routerLink="/login" class="nav-link waves-light" mdbRippleRadius>
|
|
||||||
<i class="fa fa-sign-in"></i> Connexion
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item dropdown" dropdown *ngIf="isAuthenticated()">
|
|
||||||
<a dropdownToggle mdbRippleRadius type="button" class="nav-link dropdown-toggle waves-light" mdbRippleRadius>
|
|
||||||
<i class="fa fa-user-circle"></i> Mon Compte
|
|
||||||
</a>
|
|
||||||
<div *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown dropdown-primary" role="menu">
|
|
||||||
<a class="dropdown-item waves-light" mdbRippleRadius routerLink="/myPosts">
|
|
||||||
<i class="fa fa-list-alt"></i> Mes articles
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item waves-light" mdbRippleRadius routerLink="/accountSettings">
|
|
||||||
<i class="fa fa-gear"></i> Paramètres
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item waves-light danger-color-dark" mdbRippleRadius routerLink="/disconnection">
|
|
||||||
<span class="white-text">
|
|
||||||
<i class="fa fa-sign-out"></i> Déconnexion
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<a (click)="openSidebar()">
|
|
||||||
<i id="sidebarButton" class="fa fa-lg fa-bars white-text"></i>
|
|
||||||
</a>
|
|
||||||
</links>
|
|
||||||
</mdb-navbar>
|
|
||||||
|
|
||||||
<div id="sidenav" class="sidenav">
|
|
||||||
<h3>Catégories</h3>
|
|
||||||
<a class="closebtn" (click)="closeSidebar()">
|
|
||||||
<i class="fa fa-chevron-left"></i>
|
|
||||||
</a>
|
|
||||||
<div *ngFor="let category of listCategories">
|
|
||||||
<a [id]="'category-' + category.id" class="collapsible" *ngIf="category.listSubCategories.length" (click)="openCategoriesLinks(category)">
|
|
||||||
{{category.name}} <i class="fa fa-chevron-down pull-right"></i>
|
|
||||||
</a>
|
|
||||||
<div class="categoriesLinks" >
|
|
||||||
<a *ngFor="let subCategory of category.listSubCategories"
|
|
||||||
(click)="openPostsByCategory(subCategory.id)">
|
|
||||||
{{subCategory.name}}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="overlay" (click)="closeSidebar()"></div>
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#title {
|
|
||||||
color: white;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
margin-top: -7px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebarButton {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The side navigation menu */
|
|
||||||
.sidenav {
|
|
||||||
height: 100%; /* 100% Full-height */
|
|
||||||
width: 0; /* 0 width - change this with JavaScript */
|
|
||||||
position: fixed; /* Stay in place */
|
|
||||||
z-index: 1000; /* Stay on top */
|
|
||||||
top: 0; /* Stay at the top */
|
|
||||||
left: 0;
|
|
||||||
background-color: #3f51b5;
|
|
||||||
overflow-x: hidden; /* Disable horizontal scroll */
|
|
||||||
padding-top: 20px; /* Place content 60px from the top */
|
|
||||||
transition: 0.3s; /* 0.5 second transition effect to slide in the sidenav */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The navigation menu links */
|
|
||||||
.sidenav a {
|
|
||||||
padding: 8px 32px 8px 32px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: white;
|
|
||||||
display: block;
|
|
||||||
transition: 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When you mouse over the navigation links, change their color */
|
|
||||||
.sidenav a:hover {
|
|
||||||
color: #ccc;
|
|
||||||
background-color: #5c6bc0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidenav h3 {
|
|
||||||
padding: 8px 8px 8px 32px;
|
|
||||||
color: white;
|
|
||||||
padding-bottom: 25px;
|
|
||||||
border-bottom: 1px solid #5c6bc0;
|
|
||||||
}
|
|
||||||
/* Position and style the close button (top right corner) */
|
|
||||||
.sidenav .closebtn {
|
|
||||||
position: absolute;
|
|
||||||
top: 25px;
|
|
||||||
right: 25px;
|
|
||||||
margin-left: 50px;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
|
|
||||||
@media screen and (max-height: 450px) {
|
|
||||||
.sidenav {padding-top: 15px;}
|
|
||||||
.sidenav a {font-size: 18px;}
|
|
||||||
}
|
|
||||||
|
|
||||||
#overlay {
|
|
||||||
position: fixed; /* Sit on top of the page content */
|
|
||||||
display: none; /* Hidden by default */
|
|
||||||
width: 100%; /* Full width (cover the whole page) */
|
|
||||||
height: 100%; /* Full height (cover the whole page) */
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0,0,0,0.5); /* Black background with opacity */
|
|
||||||
z-index: 999; /* Specify a stack order in case you're using a different order for other elements */
|
|
||||||
transition: 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.categoriesLinks {
|
|
||||||
background-color: #303f9f;
|
|
||||||
max-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.2s ease-out;
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { AuthService } from '../core/services/auth.service';
|
|
||||||
import { Category } from '../core/entities';
|
|
||||||
import { HeaderService } from './header.service';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const SIDENAV_WIDTH = '300px';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-header',
|
|
||||||
templateUrl: './header.component.html',
|
|
||||||
styleUrls: ['./header.component.scss']
|
|
||||||
})
|
|
||||||
export class HeaderComponent implements OnInit {
|
|
||||||
isAdmin: boolean;
|
|
||||||
listCategories: Array<Category> = [];
|
|
||||||
title: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private authService: AuthService,
|
|
||||||
private headerService: HeaderService,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.title = environment.title;
|
|
||||||
this.isAdmin = this.authService.isAdmin();
|
|
||||||
this.headerService.getAllCategories().subscribe(listCategories => {
|
|
||||||
this.listCategories = listCategories;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
isAuthenticated(): boolean {
|
|
||||||
// console.log('Checking if user is connected... for header');
|
|
||||||
return this.authService.isAuthenticated();
|
|
||||||
}
|
|
||||||
|
|
||||||
openSidebar(): void {
|
|
||||||
document.getElementById('sidenav').style.width = SIDENAV_WIDTH;
|
|
||||||
document.getElementById('overlay').style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
closeSidebar(): void {
|
|
||||||
document.getElementById('sidenav').style.width = '0';
|
|
||||||
document.getElementById('overlay').style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect the user to the page to show the posts of the category which its id is in parameters.
|
|
||||||
*
|
|
||||||
* @param categoryId The id of the category which we need to show its posts after redirection.
|
|
||||||
*/
|
|
||||||
openPostsByCategory(categoryId: string): void {
|
|
||||||
this.closeSidebar();
|
|
||||||
|
|
||||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
|
||||||
this.router.navigateByUrl('/posts/byCategory/' + categoryId).then(() => {
|
|
||||||
this.router.navigated = false;
|
|
||||||
this.router.navigate([this.router.url]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the accordion which correspond to the category in parameters.
|
|
||||||
*
|
|
||||||
* @param category The category which its accodion needs to be open.
|
|
||||||
*/
|
|
||||||
openCategoriesLinks(category: Category): void {
|
|
||||||
const divCategoriesLinks = document.getElementById('category-' + category.id);
|
|
||||||
|
|
||||||
divCategoriesLinks.classList.toggle('active');
|
|
||||||
const divContent = divCategoriesLinks.nextElementSibling as HTMLElement;
|
|
||||||
if (divContent.style.maxHeight) {
|
|
||||||
divContent.style.maxHeight = null;
|
|
||||||
} else {
|
|
||||||
divContent.style.maxHeight = divContent.scrollHeight + 'px';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { Category } from '../core/entities';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const CATEGORY_URL = environment.apiUrl + '/api/categories/';
|
|
||||||
@Injectable()
|
|
||||||
export class HeaderService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
getAllCategories(): Observable<Array<Category>> {
|
|
||||||
return this.http.get<Array<Category>>(CATEGORY_URL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<div>
|
|
||||||
<h1>Derniers articles</h1>
|
|
||||||
<app-spinner *ngIf="!listArticle"></app-spinner>
|
|
||||||
<div *ngIf="listArticle" class="col-lg-8 offset-lg-2">
|
|
||||||
<app-post-card *ngFor="let post of listArticle" [post]="post"></app-post-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
div.card {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
import { HomeService } from './home.service';
|
|
||||||
import { Post } from '../core/entities';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-home',
|
|
||||||
templateUrl: './home.component.html',
|
|
||||||
styleUrls: ['./home.component.scss']
|
|
||||||
})
|
|
||||||
export class HomeComponent implements OnInit {
|
|
||||||
listArticle: Array<Post>;
|
|
||||||
title: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private homeService: HomeService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.homeService.getLastPosts().subscribe(lastPosts => {
|
|
||||||
this.listArticle = lastPosts;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { Post } from '../core/entities';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const POSTS_URL = environment.apiUrl + '/api/posts';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class HomeService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
getLastPosts(): Observable<Array<Post>> {
|
|
||||||
return this.http.get<Array<Post>>(POSTS_URL + '/last');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<div class="card col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
|
||||||
<div class="card-body">
|
|
||||||
<h4 class="card-title">Connexion</h4>
|
|
||||||
<form id="form" (ngSubmit)="onSubmit()" #loginForm="ngForm">
|
|
||||||
<div class="md-form">
|
|
||||||
<i class="fa fa-envelope prefix grey-text"></i>
|
|
||||||
<input mdbActive
|
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.email"
|
|
||||||
#email="ngModel"
|
|
||||||
data-error="Veuillez saisir une adresse email valide"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="email">Email</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<i class="fa fa-lock prefix grey-text"></i>
|
|
||||||
<input mdbActive
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.password"
|
|
||||||
#password="ngModel"
|
|
||||||
data-error="Veuillez saisir votre mot de passe"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="password">Password</label>
|
|
||||||
</div>
|
|
||||||
<div id="errorMsg" class="card red lighten-2 text-center z-depth-2">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{loginError}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col submitFormArea">
|
|
||||||
<a routerLink="/signin" class="indigo-text">
|
|
||||||
Je n'ai pas de compte
|
|
||||||
</a>
|
|
||||||
<button class="float-right waves-effect waves-light indigo btn"
|
|
||||||
type="submit" [disabled]="!loginForm.form.valid">
|
|
||||||
Suivant
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { User } from '../core/entities';
|
|
||||||
import { AuthService } from '../core/services/auth.service';
|
|
||||||
import { LoginService } from './login.service';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-login',
|
|
||||||
templateUrl: './login.component.html',
|
|
||||||
styles: [`
|
|
||||||
#form {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submitFormArea {
|
|
||||||
line-height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#errorMsg {
|
|
||||||
max-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.5s ease-out;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class LoginComponent {
|
|
||||||
model: User = new User('', '', '', '', '', null, null, '');
|
|
||||||
loginError: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private loginService: LoginService,
|
|
||||||
private authService: AuthService,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
onSubmit(): void {
|
|
||||||
this.loginError = undefined;
|
|
||||||
|
|
||||||
this.loginService.login(this.model).subscribe(user => {
|
|
||||||
// this.authService.setToken(user.token);
|
|
||||||
this.authService.setAuthenticated(true);
|
|
||||||
this.authService.setUser(user);
|
|
||||||
this.router.navigate(['/myPosts']);
|
|
||||||
}, error => {
|
|
||||||
this.setMessage('Email ou password incorrect.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setMessage(message: string): void {
|
|
||||||
this.loginError = message;
|
|
||||||
|
|
||||||
const resultMsgDiv = document.getElementById('errorMsg');
|
|
||||||
resultMsgDiv.style.maxHeight = '64px';
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
resultMsgDiv.style.maxHeight = '0px';
|
|
||||||
setTimeout(() => {
|
|
||||||
this.loginError = undefined;
|
|
||||||
}, 550);
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
||||||
import { RequestOptions } from '@angular/http';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
import { User } from '../core/entities';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const LOGIN_URL = environment.apiUrl + '/api/account/login';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class LoginService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
login(user: User): Observable<User> {
|
|
||||||
const options = { withCredentials: true };
|
|
||||||
return this.http.post<User>('/api/account/login', user, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-not-found',
|
|
||||||
template: `
|
|
||||||
<div class="text-center">
|
|
||||||
<img src="./assets/images/404.png" alt="404" />
|
|
||||||
<h3>Page non trouvée...</h3>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
})
|
|
||||||
export class NotFoundComponent {}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<div>
|
|
||||||
<app-spinner *ngIf="!listPosts"></app-spinner>
|
|
||||||
<h1 *ngIf="listPosts">Catégorie {{category.name}}</h1>
|
|
||||||
<div *ngIf="listPosts" class="col-lg-8 offset-lg-2">
|
|
||||||
<app-post-card *ngFor="let post of listPosts" [post]="post"></app-post-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
|
||||||
|
|
||||||
import { Post, Category } from '../../core/entities';
|
|
||||||
import { ByCategoryService } from './by-category.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-posts-by-category',
|
|
||||||
templateUrl: './by-category.component.html'
|
|
||||||
})
|
|
||||||
export class ByCategoryComponent implements OnInit {
|
|
||||||
category: Category;
|
|
||||||
listPosts: Array<Post>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private byCategoryService: ByCategoryService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
// Get the category
|
|
||||||
this.byCategoryService.getCategoryById(+this.route.snapshot.paramMap.get('categoryId')).subscribe(category => {
|
|
||||||
this.category = category;
|
|
||||||
|
|
||||||
// Get the posts by category
|
|
||||||
this.byCategoryService.getPostsByCategory(this.category).subscribe(listPosts => {
|
|
||||||
this.listPosts = listPosts;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { Post, Category } from '../../core/entities';
|
|
||||||
|
|
||||||
const CATEGORIES_URL = environment.apiUrl + '/api/categories';
|
|
||||||
const POSTS_URL = environment.apiUrl + '/api/posts';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ByCategoryService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
getCategoryById(categoryId: number): Observable<Category> {
|
|
||||||
return this.http.get<Category>(`${CATEGORIES_URL}/${categoryId}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
getPostsByCategory(category: Category): Observable<Array<Post>> {
|
|
||||||
return this.http.get<Array<Post>>(`${POSTS_URL}/byCategory/${category.id}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
<div class="card hoverable">
|
|
||||||
<div class="card-header indigo white-text" mdbRippleRadius>
|
|
||||||
<h1 *ngIf="!model.key">Création d'un article</h1>
|
|
||||||
<h1 *ngIf="model.key">Modification de l'article {{model.key}}</h1>
|
|
||||||
<div class="row">
|
|
||||||
<a class="waves-light tabs"
|
|
||||||
[ngClass]="{'active': activatedTab === 'Édition'}"
|
|
||||||
(click)="activateEdition()">
|
|
||||||
Édition
|
|
||||||
</a>
|
|
||||||
<a class="waves-light tabs"
|
|
||||||
[ngClass]="{'active': activatedTab === 'Aperçu'}"
|
|
||||||
(click)="activatePreview()">
|
|
||||||
Aperçu
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div *ngIf="activatedTab === 'Édition'">
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="title"
|
|
||||||
name="title"
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.title"
|
|
||||||
#title="ngModel"
|
|
||||||
data-error="Veuillez saisir un titre d'article"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="title">Titre de l'article</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="image"
|
|
||||||
name="image"
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.image"
|
|
||||||
#image="ngModel"
|
|
||||||
data-error="Veuillez saisir une adresse URL ou uploader une image"
|
|
||||||
data-success=""
|
|
||||||
required />
|
|
||||||
<label for="image">Image de l'article</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<input mdbActive
|
|
||||||
id="description"
|
|
||||||
name="description"
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.description"
|
|
||||||
#description="ngModel"
|
|
||||||
data-error="Veuillez saisir la description de l'article"
|
|
||||||
data-success=""
|
|
||||||
required />
|
|
||||||
<label for="description">Description de l'article</label>
|
|
||||||
</div>
|
|
||||||
<div class="input-group mb-3 wrap">
|
|
||||||
<div class="select">
|
|
||||||
<select id="category" class="select-text" [(ngModel)]="model.category" required>
|
|
||||||
<option value="" disabled selected></option>
|
|
||||||
<option *ngFor="let category of listCategories" [ngValue]="category">{{category.name}}</option>
|
|
||||||
</select>
|
|
||||||
<span class="select-highlight"></span>
|
|
||||||
<span class="select-bar"></span>
|
|
||||||
<label class="select-label">Catégorie de l'article</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="toolbox" class="row">
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-floating waves-light"
|
|
||||||
(click)="injectHeader('h1')"
|
|
||||||
mdbTooltip="Titre 1"
|
|
||||||
placement="bottom"
|
|
||||||
mdbRippleRadius>H1</button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-floating waves-light"
|
|
||||||
(click)="injectHeader('h2')"
|
|
||||||
mdbTooltip="Titre 2"
|
|
||||||
placement="bottom"
|
|
||||||
mdbRippleRadius>H2</button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-floating waves-light"
|
|
||||||
(click)="injectHeader('h3')"
|
|
||||||
mdbTooltip="Titre 3"
|
|
||||||
placement="bottom"
|
|
||||||
mdbRippleRadius>H3</button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-floating waves-light"
|
|
||||||
(click)="openImagesModal()"
|
|
||||||
mdbTooltip="Image"
|
|
||||||
placement="bottom"
|
|
||||||
mdbRippleRadius>
|
|
||||||
<i class="fa fa-image"></i>
|
|
||||||
</button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-floating waves-light"
|
|
||||||
(click)="injectLink()"
|
|
||||||
mdbTooltip="Lien"
|
|
||||||
placement="bottom"
|
|
||||||
mdbRippleRadius>
|
|
||||||
<i class="fa fa-link"></i>
|
|
||||||
</button>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-floating waves-light"
|
|
||||||
(click)="frameCode.show()"
|
|
||||||
mdbTooltip="Extrait de code"
|
|
||||||
placement="bottom"
|
|
||||||
mdbRippleRadius>
|
|
||||||
<i class="fa fa-code"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<textarea mdbActive
|
|
||||||
id="text"
|
|
||||||
name="text"
|
|
||||||
type="text"
|
|
||||||
class="md-textarea"
|
|
||||||
[(ngModel)]="model.text"
|
|
||||||
#text="ngModel"
|
|
||||||
data-error="Veuillez saisir le contenu de l'article"
|
|
||||||
data-sucess=""
|
|
||||||
required>
|
|
||||||
</textarea>
|
|
||||||
<label for="text">Contenu de l'article</label>
|
|
||||||
</div>
|
|
||||||
<div id="errorMsg" class="card red lighten-2 text-center z-depth-2">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{modelError}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="resultMsg" class="card green lighten-2 text-center z-depth-2" >
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{result}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="activatedTab === 'Aperçu'">
|
|
||||||
<app-spinner *ngIf="!parsedPost"></app-spinner>
|
|
||||||
<div class="card" *ngIf="parsedPost">
|
|
||||||
<img [src]="parsedPost.image" class="img-fluid" alt="Post image">
|
|
||||||
<div class="card-body">
|
|
||||||
<h1 class="card-title">{{parsedPost.title}}</h1>
|
|
||||||
<h4>{{parsedPost.description}}</h4>
|
|
||||||
<hr/>
|
|
||||||
<div [innerHTML]="getContent()"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="footer">
|
|
||||||
<a routerLink="/myPosts">Annuler</a>
|
|
||||||
<button type="button"
|
|
||||||
class="btn btn-primary waves-light float-right"
|
|
||||||
(click)="save()" mdbRippleRadius>Enregistrer</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div mdbModal #frameCode="mdb-modal" class="modal fade top"
|
|
||||||
tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-full-height modal-top" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title w-100" id="myModalLabel">Ajout de code</h4>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="frameCode.hide()">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="wrap">
|
|
||||||
<div class="select">
|
|
||||||
<select id="languageTmp" class="select-text" [(ngModel)]="languageTmp" required>
|
|
||||||
<option value="" disabled selected></option>
|
|
||||||
<option value="java">Java</option>
|
|
||||||
<option value="python">Python</option>
|
|
||||||
<option value="markup">html/xml</option>
|
|
||||||
<option value="sql">SQL</option>
|
|
||||||
<option value="bash">Bash</option>
|
|
||||||
</select>
|
|
||||||
<span class="select-highlight"></span>
|
|
||||||
<span class="select-bar"></span>
|
|
||||||
<label class="select-label">Langage de programmation</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="md-form" style="margin-top: 15px; margin-bottom: 0;">
|
|
||||||
<textarea mdbActive
|
|
||||||
id="codeTmp"
|
|
||||||
name="codeTmp"
|
|
||||||
type="text"
|
|
||||||
class="md-textarea"
|
|
||||||
[(ngModel)]="codeTmp"
|
|
||||||
required>
|
|
||||||
</textarea>
|
|
||||||
<label for="codeTmp">Extrait de code</label>
|
|
||||||
</div>
|
|
||||||
<div class="card red lighten-1 text-center z-depth-2" [hidden]="!codeError" style="margin-bottom: 0;">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">Le langage et l'extrait de code doivent être renseignés.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-outline-primary waves-effect waves-light"
|
|
||||||
data-dismiss="modal" (click)="frameCode.hide()">Fermer</button>
|
|
||||||
<button type="button" class="btn btn-primary waves-effect waves-light"
|
|
||||||
(click)="injectCode()">Enregistrer</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div mdbModal #frameImages="mdb-modal" class="modal fade top"
|
|
||||||
tabindex="-1" role="dialog" aria-labelledby="frameImagesLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-full-height modal-top" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4 class="modal-title w-100" id="frameImagesLabel">Ajout d'image</h4>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="frameCode.hide()">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<app-spinner *ngIf="!imagesLoaded"></app-spinner>
|
|
||||||
<div id="image-div" *ngIf="imagesLoaded">
|
|
||||||
<img *ngFor="let img of listImages"
|
|
||||||
[src]="getLinkSrc(img.link)"
|
|
||||||
class="uploaded-image hoverable"
|
|
||||||
(click)="injectImage(img.link)" />
|
|
||||||
</div>
|
|
||||||
<a class="fixed-action-btn green white-text" *ngIf="imagesLoaded" (click)="openNewImageInput()">+</a>
|
|
||||||
<input id="newImageInput" type="file" (change)="uploadImage($event)" [hidden]="true">
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-outline-primary waves-effect waves-light"
|
|
||||||
data-dismiss="modal" (click)="frameImages.hide()">Fermer</button>
|
|
||||||
<button type="button" class="btn btn-primary waves-effect waves-light"
|
|
||||||
(click)="injectCode()">Enregistrer</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
.card {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
padding-top: 24px;
|
|
||||||
padding-left: 24px;
|
|
||||||
padding-right: 24px;
|
|
||||||
padding-bottom: 0px;
|
|
||||||
border-width: 0px;
|
|
||||||
}
|
|
||||||
.tabs {
|
|
||||||
width: 50%;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 62px;
|
|
||||||
}
|
|
||||||
.tabs.active {
|
|
||||||
border-bottom: 4px solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
height: 250px;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-select {
|
|
||||||
border: 0px;
|
|
||||||
border-bottom: 1px #aaa solid;
|
|
||||||
border-radius: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.custom-select:focus {
|
|
||||||
-webkit-box-shadow: 0;
|
|
||||||
box-shadow: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-form {
|
|
||||||
margin-bottom: 35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#footer {
|
|
||||||
line-height: 57px;
|
|
||||||
padding-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#toolbox {
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-floating {
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 0;
|
|
||||||
margin: 2px;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
background-color: #3f51b5;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
|
|
||||||
transition: box-shadow 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-floating:hover {
|
|
||||||
box-shadow: 0 8px 17px 0 rgba(0,0,0,.2), 0 6px 20px 0 rgba(0,0,0,.19);
|
|
||||||
}
|
|
||||||
|
|
||||||
#text {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#resultMsg, #errorMsg {
|
|
||||||
max-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.5s ease-out;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.wrap {
|
|
||||||
top: 40%;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* select starting stylings ------------------------------*/
|
|
||||||
.select {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-text {
|
|
||||||
position: relative;
|
|
||||||
font-family: inherit;
|
|
||||||
background-color: transparent;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 10px 10px 0;
|
|
||||||
font-size: 18px;
|
|
||||||
border-radius: 0;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid #bdbdbd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove focus */
|
|
||||||
.select-text:focus {
|
|
||||||
outline: none;
|
|
||||||
border-bottom: 1px solid rgba(0,0,0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use custom arrow */
|
|
||||||
.select .select-text {
|
|
||||||
appearance: none;
|
|
||||||
-webkit-appearance:none
|
|
||||||
}
|
|
||||||
|
|
||||||
.select:after {
|
|
||||||
position: absolute;
|
|
||||||
top: 18px;
|
|
||||||
right: 10px;
|
|
||||||
/* Styling the down arrow */
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
padding: 0;
|
|
||||||
content: '';
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
border-top: 6px solid #bdbdbd;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* LABEL ======================================= */
|
|
||||||
.select-label {
|
|
||||||
color: #757575;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: normal;
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
left: 0;
|
|
||||||
top: -5px;
|
|
||||||
transition: 0.2s ease all;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* active state */
|
|
||||||
.select-text:focus ~ .select-label {
|
|
||||||
color: #2F80ED;
|
|
||||||
}
|
|
||||||
.select-text:focus ~ .select-label, .select-text:valid ~ .select-label {
|
|
||||||
top: -20px;
|
|
||||||
transition: 0.2s ease all;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BOTTOM BARS ================================= */
|
|
||||||
.select-bar {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-bar:before, .select-bar:after {
|
|
||||||
content: '';
|
|
||||||
height: 2px;
|
|
||||||
width: 0;
|
|
||||||
bottom: 1px;
|
|
||||||
position: absolute;
|
|
||||||
background: #2F80ED;
|
|
||||||
transition: 0.2s ease all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-bar:before {
|
|
||||||
left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-bar:after {
|
|
||||||
right: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* active state */
|
|
||||||
.select-text:focus ~ .select-bar:before, .select-text:focus ~ .select-bar:after {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HIGHLIGHTER ================================== */
|
|
||||||
.select-highlight {
|
|
||||||
position: absolute;
|
|
||||||
height: 60%;
|
|
||||||
width: 40%;
|
|
||||||
top: 25%;
|
|
||||||
left: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$btnSize: 45px;
|
|
||||||
|
|
||||||
.fixed-action-btn {
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
right: 40px;
|
|
||||||
z-index: 997;
|
|
||||||
width: $btnSize;
|
|
||||||
height: $btnSize;
|
|
||||||
border-radius: 50%;
|
|
||||||
line-height: $btnSize;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 25px;
|
|
||||||
box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
|
|
||||||
transition: box-shadow 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
.fixed-action-btn:hover {
|
|
||||||
box-shadow: 0 8px 17px 0 rgba(0,0,0,.2), 0 6px 20px 0 rgba(0,0,0,.19);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#image-div {
|
|
||||||
height: 60vh;
|
|
||||||
overflow-y: scroll;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uploaded-image {
|
|
||||||
display: inline-flex;
|
|
||||||
position: relative;
|
|
||||||
width: 300px;
|
|
||||||
height: 300px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14),0 3px 1px -2px rgba(0,0,0,0.12),0 1px 5px 0 rgba(0,0,0,0.2);
|
|
||||||
cursor:pointer;
|
|
||||||
margin-right: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
@@ -1,232 +0,0 @@
|
|||||||
import { Component, OnInit, SecurityContext, ViewChild } from '@angular/core';
|
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
|
||||||
import { Router, ActivatedRoute, RoutesRecognized } from '@angular/router';
|
|
||||||
|
|
||||||
import { Post, Category, Image } from '../../core/entities';
|
|
||||||
import { AuthService } from '../../core/services/auth.service';
|
|
||||||
import { CreateUpdatePostService } from './create-update-post.service';
|
|
||||||
|
|
||||||
import { filter } from 'rxjs/operators';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { HttpEventType, HttpResponse } from '@angular/common/http';
|
|
||||||
|
|
||||||
enum Tabs {
|
|
||||||
EDITION = 'Édition',
|
|
||||||
PREVIEW = 'Aperçu'
|
|
||||||
}
|
|
||||||
|
|
||||||
declare let Prism: any;
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-create-update-post',
|
|
||||||
templateUrl: './create-update-post.component.html',
|
|
||||||
styleUrls: ['./create-update-post.component.scss']
|
|
||||||
})
|
|
||||||
export class CreateUpdatePostComponent implements OnInit {
|
|
||||||
static INPUT_POST_TEXT = 'text';
|
|
||||||
|
|
||||||
@ViewChild('frameCode') public contentModal;
|
|
||||||
@ViewChild('frameImages') public imagesModal;
|
|
||||||
|
|
||||||
model: Post = new Post('', '', '', '', '', null, null, null);
|
|
||||||
parsedPost: Post;
|
|
||||||
|
|
||||||
listCategories: Array<Category>;
|
|
||||||
|
|
||||||
activatedTab: string;
|
|
||||||
|
|
||||||
modelError: string;
|
|
||||||
result: string;
|
|
||||||
|
|
||||||
// Variables for the code popup
|
|
||||||
codeTmp: string;
|
|
||||||
languageTmp: string;
|
|
||||||
codeError: string;
|
|
||||||
|
|
||||||
// Variables for the images popup
|
|
||||||
imagesLoaded: boolean;
|
|
||||||
listImages: Array<Image>;
|
|
||||||
selectedFiles: FileList;
|
|
||||||
currentFileUpload: File;
|
|
||||||
progress: { percentage: number } = { percentage: 0 };
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private createUpdatePostService: CreateUpdatePostService,
|
|
||||||
private activatedRoute: ActivatedRoute,
|
|
||||||
private sanitizer: DomSanitizer,
|
|
||||||
private router: Router,
|
|
||||||
private authService: AuthService
|
|
||||||
) {
|
|
||||||
this.imagesLoaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.listCategories = [];
|
|
||||||
this.activatedTab = Tabs.EDITION;
|
|
||||||
this.createUpdatePostService.getCategories().subscribe(listCategories => {
|
|
||||||
this.listCategories = listCategories.filter(category => !category.listSubCategories.length);
|
|
||||||
});
|
|
||||||
|
|
||||||
const postKey = this.activatedRoute.snapshot.paramMap.get('postKey');
|
|
||||||
if (postKey) {
|
|
||||||
this.createUpdatePostService.getPost(postKey).subscribe(post => {
|
|
||||||
if (post.author.key === this.authService.getUser().key) {
|
|
||||||
this.model = post;
|
|
||||||
} else {
|
|
||||||
this.router.navigate(['/forbidden']);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// this.router.events.filter(e => e instanceof RoutesRecognized).pairwise().subscribe((event: any[]) => {
|
|
||||||
// if (event[0].urlAfterRedirects === '/posts/new') {
|
|
||||||
// this.result = 'Article créé.';
|
|
||||||
// setTimeout(() => {
|
|
||||||
// this.result = undefined;
|
|
||||||
// }, 3500);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
activateEdition(): void {
|
|
||||||
this.activatedTab = Tabs.EDITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
activatePreview(): void {
|
|
||||||
this.activatedTab = Tabs.PREVIEW;
|
|
||||||
this.parsedPost = undefined;
|
|
||||||
this.createUpdatePostService.processPreview(this.model).subscribe(parsedPost => {
|
|
||||||
this.parsedPost = parsedPost;
|
|
||||||
setTimeout(() => {
|
|
||||||
Prism.highlightAll();
|
|
||||||
}, 100);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getContent(): string {
|
|
||||||
return this.sanitizer.sanitize(SecurityContext.HTML, this.parsedPost.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
injectHeader(header: string): void {
|
|
||||||
this.injectElement('[' + header + '][/' + header + ']', 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
injectLink(): void {
|
|
||||||
this.injectElement('[link href="" txt="" /]', 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
injectCode(): void {
|
|
||||||
if (this.languageTmp && this.codeTmp) {
|
|
||||||
const codeExtract = '\n[code lg="' + this.languageTmp + '"]\n'
|
|
||||||
+ this.codeTmp + '\n[/code]\n\n';
|
|
||||||
|
|
||||||
this.injectElement(codeExtract, codeExtract.length);
|
|
||||||
|
|
||||||
this.contentModal.hide();
|
|
||||||
|
|
||||||
this.codeTmp = undefined;
|
|
||||||
this.languageTmp = undefined;
|
|
||||||
this.resetSelect('languageTmp');
|
|
||||||
} else {
|
|
||||||
this.codeError = 'Le langage et l\'extrait de code doivent être renseignés.';
|
|
||||||
setTimeout(() => {
|
|
||||||
this.codeError = undefined;
|
|
||||||
}, 3500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private injectElement(elementToInject: string, lengthForCursor: number): void {
|
|
||||||
const input = <HTMLInputElement>document.getElementById(CreateUpdatePostComponent.INPUT_POST_TEXT);
|
|
||||||
const contentValue = input.value;
|
|
||||||
const cursorPosition = input.selectionStart;
|
|
||||||
|
|
||||||
this.model.text = contentValue.slice(0, cursorPosition) + elementToInject + contentValue.slice(cursorPosition);
|
|
||||||
input.focus();
|
|
||||||
const newCursor = cursorPosition + lengthForCursor;
|
|
||||||
input.selectionStart = newCursor;
|
|
||||||
input.selectionEnd = newCursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private resetSelect(selectId: string): void {
|
|
||||||
const select = <HTMLSelectElement>document.getElementById(selectId);
|
|
||||||
select.selectedIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
save(): void {
|
|
||||||
if (this.model.title && this.model.image && this.model.description && this.model.category && this.model.text) {
|
|
||||||
this.model.author = this.authService.getUser();
|
|
||||||
|
|
||||||
if (this.model.key) {
|
|
||||||
this.createUpdatePostService.updatePost(this.model).subscribe(post => {
|
|
||||||
this.setMessage('Modification enregistrée', false);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.createUpdatePostService.addPost(this.model).subscribe(post => {
|
|
||||||
this.router.navigate([`/posts/update/${post.key}`]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.setMessage('Veuillez saisir les champs obligatoires.', true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setMessage(message: string, error: boolean): void {
|
|
||||||
this[error ? 'modelError' : 'result'] = message;
|
|
||||||
|
|
||||||
const resultMsgDiv = document.getElementById(error ? 'errorMsg' : 'resultMsg');
|
|
||||||
resultMsgDiv.style.maxHeight = '64px';
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
resultMsgDiv.style.maxHeight = '0px';
|
|
||||||
setTimeout(() => {
|
|
||||||
this[error ? 'modelError' : 'result'] = undefined;
|
|
||||||
}, 550);
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
openImagesModal(): void {
|
|
||||||
this.imagesLoaded = false;
|
|
||||||
this.imagesModal.show();
|
|
||||||
|
|
||||||
this.createUpdatePostService.getImages().subscribe(listImages => {
|
|
||||||
this.listImages = listImages;
|
|
||||||
this.imagesLoaded = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getLinkSrc(pLink: string): string {
|
|
||||||
return `${environment.apiUrl}/api/images/${pLink}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
openNewImageInput(): void {
|
|
||||||
document.getElementById('newImageInput').click();
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadImage(event): void {
|
|
||||||
this.selectedFiles = event.target.files;
|
|
||||||
this.progress.percentage = 0;
|
|
||||||
|
|
||||||
this.currentFileUpload = this.selectedFiles.item(0);
|
|
||||||
// This prevents error 400 if user doesn't select any file to upload and close the input file.
|
|
||||||
if (this.currentFileUpload) {
|
|
||||||
this.createUpdatePostService.uploadPicture(this.currentFileUpload).subscribe(result => {
|
|
||||||
if (result.type === HttpEventType.UploadProgress) {
|
|
||||||
this.progress.percentage = Math.round(100 * result.loaded / result.total);
|
|
||||||
} else if (result instanceof HttpResponse) {
|
|
||||||
console.log('File ' + result.body + ' completely uploaded!');
|
|
||||||
this.createUpdatePostService.getImageDetails(result.body as string).subscribe(image => {
|
|
||||||
this.listImages.push(image);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.selectedFiles = undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
injectImage(pImageLink: string): void {
|
|
||||||
const imgTag = `[img src="${this.getLinkSrc(pImageLink)}" /]`;
|
|
||||||
this.injectElement(imgTag, imgTag.length);
|
|
||||||
this.imagesModal.hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { HttpClient, HttpEvent, HttpRequest } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { Post, Category, Image } from '../../core/entities';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const IMAGES_URL = environment.apiUrl + '/api/images';
|
|
||||||
const POSTS_URL = environment.apiUrl + '/api/posts';
|
|
||||||
const CATEGORIES_URL = environment.apiUrl + '/api/categories';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class CreateUpdatePostService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
processPreview(post: Post): Observable<Post> {
|
|
||||||
return this.http.post<Post>(`${POSTS_URL}/preview`, post);
|
|
||||||
}
|
|
||||||
|
|
||||||
getCategories(): Observable<Array<Category>> {
|
|
||||||
return this.http.get<Array<Category>>(`${CATEGORIES_URL}/`);
|
|
||||||
}
|
|
||||||
|
|
||||||
addPost(post: Post): Observable<Post> {
|
|
||||||
return this.http.post<Post>(`${POSTS_URL}/`, post);
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePost(post: Post): Observable<Post> {
|
|
||||||
return this.http.put<Post>(`${POSTS_URL}/`, post);
|
|
||||||
}
|
|
||||||
|
|
||||||
getPost(postKey: string): Observable<Post> {
|
|
||||||
return this.http.get<Post>(`${POSTS_URL}/${postKey}/source`);
|
|
||||||
}
|
|
||||||
|
|
||||||
getImages(): Observable<Array<Image>> {
|
|
||||||
return this.http.get<Array<Image>>(`${IMAGES_URL}/myImages`);
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadPicture(file: File): Observable<HttpEvent<{}>> {
|
|
||||||
const formData: FormData = new FormData();
|
|
||||||
|
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
return this.http.request(new HttpRequest(
|
|
||||||
'POST', IMAGES_URL, formData, {
|
|
||||||
reportProgress: true,
|
|
||||||
responseType: 'text'
|
|
||||||
}
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
getImageDetails(imageLink: string): Observable<Image> {
|
|
||||||
return this.http.get<Image>(`${IMAGES_URL}/${imageLink}/details`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<div>
|
|
||||||
<h1>Mes articles</h1>
|
|
||||||
<app-spinner *ngIf="!listPosts"></app-spinner>
|
|
||||||
<div *ngIf="listPosts" class="col-lg-8 offset-lg-2">
|
|
||||||
<app-post-card *ngFor="let post of listPosts" [post]="post"></app-post-card>
|
|
||||||
</div>
|
|
||||||
<a routerLink="/posts/new" class="fixed-action-btn green white-text">+</a>
|
|
||||||
</div>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
$btnSize: 55px;
|
|
||||||
|
|
||||||
.fixed-action-btn {
|
|
||||||
display: block;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 23px;
|
|
||||||
right: 23px;
|
|
||||||
z-index: 997;
|
|
||||||
width: $btnSize;
|
|
||||||
height: $btnSize;
|
|
||||||
border-radius: 50%;
|
|
||||||
line-height: $btnSize;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 30px;
|
|
||||||
box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
|
|
||||||
transition: box-shadow 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
.fixed-action-btn:hover {
|
|
||||||
box-shadow: 0 8px 17px 0 rgba(0,0,0,.2), 0 6px 20px 0 rgba(0,0,0,.19);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
|
|
||||||
import { Post } from '../../core/entities';
|
|
||||||
import { MyPostsService } from './my-posts.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-my-posts',
|
|
||||||
templateUrl: './my-posts.component.html',
|
|
||||||
styleUrls: ['./my-posts.component.scss']
|
|
||||||
})
|
|
||||||
export class MyPostsComponent implements OnInit {
|
|
||||||
listPosts: Array<Post>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private myPostsService: MyPostsService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.myPostsService.getMyPosts().subscribe(listPosts => {
|
|
||||||
this.listPosts = listPosts;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { Post } from '../../core/entities';
|
|
||||||
|
|
||||||
const POSTS_URL = environment.apiUrl + '/api/posts';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class MyPostsService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
getMyPosts(): Observable<Array<Post>> {
|
|
||||||
return this.http.get<Array<Post>>(`${POSTS_URL}/myPosts`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<div id="content" *ngIf="!notFound">
|
|
||||||
<app-spinner *ngIf="!loaded"></app-spinner>
|
|
||||||
<div class="card" *ngIf="loaded">
|
|
||||||
<img [src]="post?.image" class="img-fluid" alt="Post image">
|
|
||||||
|
|
||||||
<a *ngIf="owned" class="btn-card-floating waves-light white-text"
|
|
||||||
routerLink="/posts/update/{{post.key}}">
|
|
||||||
<i class="fa fa-pencil"></i>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="card-body">
|
|
||||||
<h1 class="card-title">{{post.title}}</h1>
|
|
||||||
<h4>{{post.description}}</h4>
|
|
||||||
<hr/>
|
|
||||||
<div [innerHTML]="getContent()"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card-data">
|
|
||||||
<img [src]="getAvatarUrl()"
|
|
||||||
class="author-img"
|
|
||||||
[alt]="post.author.name"
|
|
||||||
[mdbTooltip]="post.author.name"
|
|
||||||
placement="bottom"/>
|
|
||||||
Article écrit par {{post.author.name}}
|
|
||||||
<span class="creation-date-area">({{post.creationDate | date:'yyyy-MM-dd HH:mm:ss'}})</span>
|
|
||||||
<button *ngIf="owned" type="button" class="btn btn-danger waves-light float-right" (click)="alertDelete.show()" mdbRippleRadius>
|
|
||||||
<i class="fa fa-trash mr-1"></i> Supprimer
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div mdbModal #alertDelete="mdb-modal" class="modal fade" role="dialog" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-notify modal-danger" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<p class="heading lead">Suppression de l'article</p>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="alertDelete.hide()">
|
|
||||||
<span aria-hidden="true" class="white-text">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="text-center">
|
|
||||||
<p>Êtes vous sûr de vouloir supprimer cet article ?</p>
|
|
||||||
<p *ngIf="postDeletionFailed" class="red-text">
|
|
||||||
Une erreur est survenue lors de la suppression de l'article.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<a type="button"
|
|
||||||
class="btn btn-outline-secondary-modal"
|
|
||||||
data-dismiss="modal"
|
|
||||||
(click)="alertDelete.hide()"
|
|
||||||
mdbRippleRadius>
|
|
||||||
Annuler
|
|
||||||
</a>
|
|
||||||
<a type="button" mdbRippleRadius
|
|
||||||
class="btn btn-primary-modal waves-light"
|
|
||||||
(click)="deletePost()">
|
|
||||||
<i class="fa fa-trash"></i> Supprimer
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<app-not-found *ngIf="notFound"></app-not-found>
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
import { Component, OnInit, SecurityContext, ViewChild } from '@angular/core';
|
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
import { Post, User } from '../core/entities';
|
|
||||||
import { PostService } from './post.service';
|
|
||||||
import { AuthService } from '../core/services/auth.service';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
declare let Prism: any;
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-post',
|
|
||||||
templateUrl: './post.component.html',
|
|
||||||
styles: [`
|
|
||||||
.author-img {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.card .card-data {
|
|
||||||
padding: 15px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
#content {
|
|
||||||
margin-bottom: 50px;
|
|
||||||
}
|
|
||||||
.creation-date-area {
|
|
||||||
color: #bdbdbd;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class PostComponent implements OnInit {
|
|
||||||
post: Post = new Post('', '', '', '', '', null, new User('', '', '', '', '', null, null, ''), null);
|
|
||||||
loaded: boolean;
|
|
||||||
notFound: boolean;
|
|
||||||
owned: boolean;
|
|
||||||
|
|
||||||
@ViewChild('alertDelete') alertDelete;
|
|
||||||
|
|
||||||
postDeletionFailed: boolean;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private activatedRoute: ActivatedRoute,
|
|
||||||
private router: Router,
|
|
||||||
private postService: PostService,
|
|
||||||
private sanitizer: DomSanitizer,
|
|
||||||
private authService: AuthService
|
|
||||||
) {
|
|
||||||
this.loaded = false;
|
|
||||||
this.owned = false;
|
|
||||||
this.postDeletionFailed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.postService.getPost(this.activatedRoute.snapshot.paramMap.get('postKey')).subscribe(post => {
|
|
||||||
this.post = post;
|
|
||||||
this.loaded = true;
|
|
||||||
this.owned = this.isOwned();
|
|
||||||
setTimeout(() => {
|
|
||||||
Prism.highlightAll();
|
|
||||||
}, 100);
|
|
||||||
}, error => {
|
|
||||||
if (error instanceof HttpErrorResponse && error.status === 404) {
|
|
||||||
this.notFound = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private isOwned(): boolean {
|
|
||||||
let result = false;
|
|
||||||
|
|
||||||
const connectedUser = this.authService.getUser();
|
|
||||||
if (connectedUser) {
|
|
||||||
result = this.post.author.key === connectedUser.key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
getContent(): SafeHtml {
|
|
||||||
return this.sanitizer.sanitize(SecurityContext.HTML, this.post.text);
|
|
||||||
}
|
|
||||||
|
|
||||||
getAvatarUrl(): string {
|
|
||||||
return this.post.author.image
|
|
||||||
? `${environment.apiUrl}/api/images/loadAvatar/${this.post.author.image}`
|
|
||||||
: './assets/images/default_user.png';
|
|
||||||
}
|
|
||||||
|
|
||||||
deletePost(): void {
|
|
||||||
this.postDeletionFailed = false;
|
|
||||||
|
|
||||||
this.postService.deletePost(this.post).subscribe(() => {
|
|
||||||
this.alertDelete.hide();
|
|
||||||
this.router.navigate(['/myPosts']);
|
|
||||||
}, error => {
|
|
||||||
this.postDeletionFailed = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.postDeletionFailed = false;
|
|
||||||
}, 3500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { Post } from '../core/entities';
|
|
||||||
|
|
||||||
const POSTS_URL = environment.apiUrl + '/api/posts';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PostService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
getPost(postKey: string): Observable<Post> {
|
|
||||||
return this.http.get<Post>(`${POSTS_URL}/${postKey}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
deletePost(postToDelete: Post): Observable<any> {
|
|
||||||
return this.http.delete(`${POSTS_URL}/${postToDelete.key}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { Post } from '../core/entities';
|
|
||||||
import { SearchService } from './search.service';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-search',
|
|
||||||
template: `
|
|
||||||
<div>
|
|
||||||
<h1>Résultats de la recherche</h1>
|
|
||||||
<app-spinner *ngIf="!listArticle"></app-spinner>
|
|
||||||
<div *ngIf="listArticle" class="col-lg-8 offset-lg-2">
|
|
||||||
<app-post-card *ngFor="let post of listArticle" [post]="post"></app-post-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
})
|
|
||||||
export class SearchComponent implements OnInit {
|
|
||||||
searchLoading: boolean;
|
|
||||||
listArticle: Array<Post>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private activatedRoute: ActivatedRoute,
|
|
||||||
private searchService: SearchService
|
|
||||||
) {
|
|
||||||
this.searchLoading = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.searchService.search(this.activatedRoute.snapshot.paramMap.get('searchCriteria'))
|
|
||||||
.subscribe(listArticle => {
|
|
||||||
this.listArticle = listArticle;
|
|
||||||
this.searchLoading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
import { Post } from '../core/entities';
|
|
||||||
|
|
||||||
const POSTS_URL = environment.apiUrl + '/api/posts';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SearchService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
search(searchCriteria: string): Observable<Array<Post>> {
|
|
||||||
return this.http.get<Array<Post>>(`${POSTS_URL}/search/${searchCriteria}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
<div class="card col-md-8 offset-md-2 col-lg-6 offset-lg-3">
|
|
||||||
<div id="form" class="card-body">
|
|
||||||
<h4 class="card-title">Inscrition</h4>
|
|
||||||
<form (ngSubmit)="onSubmit()" #signinForm="ngForm">
|
|
||||||
<div class="md-form">
|
|
||||||
<i class="fa fa-id-badge prefix grey-text"></i>
|
|
||||||
<input mdbActive
|
|
||||||
id="name"
|
|
||||||
name="name"
|
|
||||||
type="text"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.name"
|
|
||||||
#name="ngModel"
|
|
||||||
data-error="Veuillez saisir un nom d'utilisateur"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="name">Nom d'utilisateur</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<i class="fa fa-envelope prefix grey-text"></i>
|
|
||||||
<input mdbActive
|
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.email"
|
|
||||||
#email="ngModel"
|
|
||||||
data-error="Veuillez saisir une adresse email valide"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="email">Email</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<i class="fa fa-lock prefix grey-text"></i>
|
|
||||||
<input mdbActive
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="model.password"
|
|
||||||
#password="ngModel"
|
|
||||||
data-error="Veuillez saisir votre mot de passe"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="password">Password</label>
|
|
||||||
</div>
|
|
||||||
<div class="md-form">
|
|
||||||
<i class="fa fa-lock prefix grey-text"></i>
|
|
||||||
<input mdbActive
|
|
||||||
id="confirmPassword"
|
|
||||||
name="confirmPassword"
|
|
||||||
type="password"
|
|
||||||
class="form-control"
|
|
||||||
[(ngModel)]="confirmPassword"
|
|
||||||
data-error="Veuillez confirmer votre mot de passe"
|
|
||||||
data-sucess=""
|
|
||||||
required />
|
|
||||||
<label for="confirmPassword">Confirmez votre mot de passe</label>
|
|
||||||
</div>
|
|
||||||
<div id="errorMsg" class="card red lighten-2 text-center z-depth-2">
|
|
||||||
<div class="card-body">
|
|
||||||
<p class="white-text mb-0">{{errorMsg}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col submitFormArea">
|
|
||||||
<a routerLink="/login" class="indigo-text">
|
|
||||||
Connexion
|
|
||||||
</a>
|
|
||||||
<button class="float-right waves-effect waves-light indigo btn"
|
|
||||||
type="submit" [disabled]="!signinForm.form.valid">
|
|
||||||
Suivant
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { User } from '../core/entities';
|
|
||||||
import { SigninService } from './signin.service';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-signin',
|
|
||||||
templateUrl: './signin.component.html',
|
|
||||||
styles: [`
|
|
||||||
#form {
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submitFormArea {
|
|
||||||
line-height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#errorMsg {
|
|
||||||
max-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: max-height 0.5s ease-out;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class SigninComponent {
|
|
||||||
model: User = new User('', '', '', '', '', null, null, '');
|
|
||||||
confirmPassword: string;
|
|
||||||
errorMsg: string;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private signinService: SigninService,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
onSubmit(): void {
|
|
||||||
if (this.confirmPassword && this.confirmPassword === this.model.password) {
|
|
||||||
this.signinService.signin(this.model).subscribe(user => {
|
|
||||||
this.router.navigate(['/login']);
|
|
||||||
}, error => {
|
|
||||||
switch (error.status) {
|
|
||||||
case 409:
|
|
||||||
this.setMessage('L\'adresse mail saisie n\'est pas disponible');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.setMessage('Une erreur est survenue lors de l\'inscription, veuillez réessayer plus tard');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.setMessage('Les mots de passe saisis ne correspondent pas');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setMessage(message: string): void {
|
|
||||||
this.errorMsg = message;
|
|
||||||
|
|
||||||
const resultMsgDiv = document.getElementById('errorMsg');
|
|
||||||
resultMsgDiv.style.maxHeight = '64px';
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
resultMsgDiv.style.maxHeight = '0px';
|
|
||||||
setTimeout(() => {
|
|
||||||
this.errorMsg = undefined;
|
|
||||||
}, 550);
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
import { User } from '../core/entities';
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const SIGNIN_URL = environment.apiUrl + '/api/account/signin';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SigninService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
signin(user: User): Observable<User> {
|
|
||||||
return this.http.post<User>(SIGNIN_URL, user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="col-md-3 col-lg-2">
|
|
||||||
<h1>Versions</h1>
|
|
||||||
<ul class="list-group">
|
|
||||||
<a *ngFor="let version of versionsList">
|
|
||||||
<li [className]="version.active ? 'list-group-item active' : 'list-group-item'"
|
|
||||||
(click)="showVersionRevision(version)">
|
|
||||||
{{version.number}}
|
|
||||||
</li>
|
|
||||||
</a>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div id="versionRevisionsArea" class="col-md-9 col-lg-10">
|
|
||||||
<div *ngIf="versionRevisionsList.length">
|
|
||||||
<h3>Ajouts de fonctionnalités</h3>
|
|
||||||
<ul>
|
|
||||||
<li *ngFor="let versionRevision of versionRevisionsList">
|
|
||||||
{{versionRevision.text}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<h4 *ngIf="!versionRevisionsList.length">Aucune nouvelle fonctionnalité pour cette version.</h4>
|
|
||||||
|
|
||||||
<div *ngIf="versionRevisionsBugfixList.length">
|
|
||||||
<h3>Correction d'anomalies</h3>
|
|
||||||
<ul>
|
|
||||||
<li *ngFor="let versionRevision of versionRevisionsBugfixList">
|
|
||||||
{{versionRevision.text}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<h4 *ngIf="!versionRevisionsBugfixList.length">Aucune correction d'anomalie pour cette version.</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { VersionRevisionService } from './version-revisions.service';
|
|
||||||
import { VersionRevision, Version } from '../core/entities';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-version-revisions',
|
|
||||||
templateUrl: 'version-revisions.component.html',
|
|
||||||
styles: [`
|
|
||||||
#versionRevisionsArea {
|
|
||||||
padding-top: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
|
||||||
#versionRevisionsArea {
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`]
|
|
||||||
})
|
|
||||||
export class VersionRevisionComponent implements OnInit {
|
|
||||||
versionsList: Array<Version>;
|
|
||||||
versionRevisionsList: Array<VersionRevision>;
|
|
||||||
versionRevisionsBugfixList: Array<VersionRevision>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private versionRevisionService: VersionRevisionService
|
|
||||||
) {
|
|
||||||
this.versionsList = [];
|
|
||||||
this.versionRevisionsList = [];
|
|
||||||
this.versionRevisionsBugfixList = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.versionRevisionService.getVersions().subscribe(versionsList => {
|
|
||||||
this.versionsList = versionsList;
|
|
||||||
this.showVersionRevision(this.versionsList[0]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
showVersionRevision(version: Version): void {
|
|
||||||
this.versionsList.forEach(versionTmp => versionTmp.active = false);
|
|
||||||
version.active = true;
|
|
||||||
|
|
||||||
this.versionRevisionService.findByVersionNumber(version.number).subscribe(versionRevisionsList => {
|
|
||||||
this.versionRevisionsList = versionRevisionsList.filter(vr => !vr.bugfix);
|
|
||||||
this.versionRevisionsBugfixList = versionRevisionsList.filter(vr => vr.bugfix);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { Version, VersionRevision } from '../core/entities';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
|
|
||||||
import { environment } from 'src/environments/environment';
|
|
||||||
|
|
||||||
const VERSION_REVISIONS_URL = environment.apiUrl + '/api/versionrevisions';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class VersionRevisionService {
|
|
||||||
constructor(
|
|
||||||
private http: HttpClient
|
|
||||||
) {}
|
|
||||||
|
|
||||||
getVersions(): Observable<Array<Version>> {
|
|
||||||
return this.http.get<Array<Version>>(`${VERSION_REVISIONS_URL}/versions`);
|
|
||||||
}
|
|
||||||
|
|
||||||
findByVersionNumber(versionNumber: string): Observable<Array<VersionRevision>> {
|
|
||||||
return this.http.get<Array<VersionRevision>>(`${VERSION_REVISIONS_URL}/${versionNumber}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,271 +0,0 @@
|
|||||||
/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+apacheconf+c+bash+batch+cpp+csharp+ruby+css-extras+django+docker+git+http+ini+java+json+latex+less+lua+makefile+markdown+nginx+php+php-extras+powershell+properties+python+jsx+rest+rust+sass+scss+scala+sql+typescript+vim+wiki+yaml&plugins=line-numbers+autolinker+file-highlight+toolbar+unescaped-markup+command-line+show-language+copy-to-clipboard */
|
|
||||||
/**
|
|
||||||
* okaidia theme for JavaScript, CSS and HTML
|
|
||||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
|
||||||
* @author ocodia
|
|
||||||
*/
|
|
||||||
|
|
||||||
code[class*="language-"],
|
|
||||||
pre[class*="language-"] {
|
|
||||||
color: #f8f8f2;
|
|
||||||
background: none;
|
|
||||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
|
||||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
|
||||||
text-align: left;
|
|
||||||
white-space: pre;
|
|
||||||
word-spacing: normal;
|
|
||||||
word-break: normal;
|
|
||||||
word-wrap: normal;
|
|
||||||
line-height: 1.5;
|
|
||||||
|
|
||||||
-moz-tab-size: 4;
|
|
||||||
-o-tab-size: 4;
|
|
||||||
tab-size: 4;
|
|
||||||
|
|
||||||
-webkit-hyphens: none;
|
|
||||||
-moz-hyphens: none;
|
|
||||||
-ms-hyphens: none;
|
|
||||||
hyphens: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Code blocks */
|
|
||||||
pre[class*="language-"] {
|
|
||||||
padding: 1em;
|
|
||||||
margin: .5em 0;
|
|
||||||
overflow: auto;
|
|
||||||
border-radius: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
:not(pre) > code[class*="language-"],
|
|
||||||
pre[class*="language-"] {
|
|
||||||
background: #272822;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
:not(pre) > code[class*="language-"] {
|
|
||||||
padding: .1em;
|
|
||||||
border-radius: .3em;
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.comment,
|
|
||||||
.token.prolog,
|
|
||||||
.token.doctype,
|
|
||||||
.token.cdata {
|
|
||||||
color: slategray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.punctuation {
|
|
||||||
color: #f8f8f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.namespace {
|
|
||||||
opacity: .7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.property,
|
|
||||||
.token.tag,
|
|
||||||
.token.constant,
|
|
||||||
.token.symbol,
|
|
||||||
.token.deleted {
|
|
||||||
color: #f92672;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.boolean,
|
|
||||||
.token.number {
|
|
||||||
color: #ae81ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.selector,
|
|
||||||
.token.attr-name,
|
|
||||||
.token.string,
|
|
||||||
.token.char,
|
|
||||||
.token.builtin,
|
|
||||||
.token.inserted {
|
|
||||||
color: #a6e22e;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.operator,
|
|
||||||
.token.entity,
|
|
||||||
.token.url,
|
|
||||||
.language-css .token.string,
|
|
||||||
.style .token.string,
|
|
||||||
.token.variable {
|
|
||||||
color: #f8f8f2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.atrule,
|
|
||||||
.token.attr-value,
|
|
||||||
.token.function {
|
|
||||||
color: #e6db74;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.keyword {
|
|
||||||
color: #66d9ef;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.regex,
|
|
||||||
.token.important {
|
|
||||||
color: #fd971f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.important,
|
|
||||||
.token.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.token.italic {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token.entity {
|
|
||||||
cursor: help;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.line-numbers {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 3.8em;
|
|
||||||
counter-reset: linenumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.line-numbers > code {
|
|
||||||
position: relative;
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-numbers .line-numbers-rows {
|
|
||||||
position: absolute;
|
|
||||||
pointer-events: none;
|
|
||||||
top: 0;
|
|
||||||
font-size: 100%;
|
|
||||||
left: -3.8em;
|
|
||||||
width: 3em; /* works for line-numbers below 1000 lines */
|
|
||||||
letter-spacing: -1px;
|
|
||||||
border-right: 1px solid #999;
|
|
||||||
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-numbers-rows > span {
|
|
||||||
pointer-events: none;
|
|
||||||
display: block;
|
|
||||||
counter-increment: linenumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-numbers-rows > span:before {
|
|
||||||
content: counter(linenumber);
|
|
||||||
color: #999;
|
|
||||||
display: block;
|
|
||||||
padding-right: 0.8em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.token a {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
pre.code-toolbar {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar > .toolbar {
|
|
||||||
position: absolute;
|
|
||||||
top: .3em;
|
|
||||||
right: .2em;
|
|
||||||
transition: opacity 0.3s ease-in-out;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar:hover > .toolbar {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar > .toolbar .toolbar-item {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar > .toolbar a {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar > .toolbar button {
|
|
||||||
background: none;
|
|
||||||
border: 0;
|
|
||||||
color: inherit;
|
|
||||||
font: inherit;
|
|
||||||
line-height: normal;
|
|
||||||
overflow: visible;
|
|
||||||
padding: 0;
|
|
||||||
-webkit-user-select: none; /* for button */
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar > .toolbar a,
|
|
||||||
pre.code-toolbar > .toolbar button,
|
|
||||||
pre.code-toolbar > .toolbar span {
|
|
||||||
color: #bbb;
|
|
||||||
font-size: .8em;
|
|
||||||
padding: 0 .5em;
|
|
||||||
background: #f5f2f0;
|
|
||||||
background: rgba(224, 224, 224, 0.2);
|
|
||||||
box-shadow: 0 2px 0 0 rgba(0,0,0,0.2);
|
|
||||||
border-radius: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.code-toolbar > .toolbar a:hover,
|
|
||||||
pre.code-toolbar > .toolbar a:focus,
|
|
||||||
pre.code-toolbar > .toolbar button:hover,
|
|
||||||
pre.code-toolbar > .toolbar button:focus,
|
|
||||||
pre.code-toolbar > .toolbar span:hover,
|
|
||||||
pre.code-toolbar > .toolbar span:focus {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fallback, in case JS does not run, to ensure the code is at least visible */
|
|
||||||
.lang-markup script[type='text/plain'],
|
|
||||||
.language-markup script[type='text/plain'],
|
|
||||||
script[type='text/plain'].lang-markup,
|
|
||||||
script[type='text/plain'].language-markup {
|
|
||||||
display: block;
|
|
||||||
font: 100% Consolas, Monaco, monospace;
|
|
||||||
white-space: pre;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.command-line-prompt {
|
|
||||||
border-right: 1px solid #999;
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
font-size: 100%;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
margin-right: 1em;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.command-line-prompt > span:before {
|
|
||||||
color: #999;
|
|
||||||
content: ' ';
|
|
||||||
display: block;
|
|
||||||
padding-right: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.command-line-prompt > span[data-user]:before {
|
|
||||||
content: "[" attr(data-user) "@" attr(data-host) "] $";
|
|
||||||
}
|
|
||||||
|
|
||||||
.command-line-prompt > span[data-user="root"]:before {
|
|
||||||
content: "[" attr(data-user) "@" attr(data-host) "] #";
|
|
||||||
}
|
|
||||||
|
|
||||||
.command-line-prompt > span[data-prompt]:before {
|
|
||||||
content: attr(data-prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 822 KiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 36 KiB |
@@ -1,51 +0,0 @@
|
|||||||
/* http://prismjs.com/download.html?themes=prism-okaidia&languages=markup+css+clike+javascript+apacheconf+c+bash+batch+cpp+csharp+ruby+css-extras+django+docker+git+http+ini+java+json+latex+less+lua+makefile+markdown+nginx+php+php-extras+powershell+properties+python+jsx+rest+rust+sass+scss+scala+sql+typescript+vim+wiki+yaml&plugins=line-numbers+autolinker+file-highlight+toolbar+unescaped-markup+command-line+show-language+copy-to-clipboard */
|
|
||||||
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case"Array":return e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var o={};for(var s in i)if(i.hasOwnProperty(s)){if(s==t)for(var l in a)a.hasOwnProperty(l)&&(o[l]=a[l]);o[s]=i[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var i in e)e.hasOwnProperty(i)&&(t.call(e,i,e[i],a||i),"Object"!==n.util.type(e[i])||r[n.util.objId(e[i])]?"Array"!==n.util.type(e[i])||r[n.util.objId(e[i])]||(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,i,r)):(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var r,i=a.elements||document.querySelectorAll(a.selector),l=0;r=i[l++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var i,l,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(i=(o.className.match(e)||[,""])[1].toLowerCase(),l=n.languages[i]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+i,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+i);var s=t.textContent,u={element:t,language:i,grammar:l,code:s};if(n.hooks.run("before-sanity-check",u),!u.code||!u.grammar)return u.code&&(n.hooks.run("before-highlight",u),u.element.textContent=u.code,n.hooks.run("after-highlight",u)),n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),a&&_self.Worker){var g=new Worker(n.filename);g.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},g.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,r){var i=n.tokenize(e,t);return a.stringify(n.util.encode(i),r)},matchGrammar:function(e,t,a,r,i,l,o){var s=n.Token;for(var u in a)if(a.hasOwnProperty(u)&&a[u]){if(u==o)return;var g=a[u];g="Array"===n.util.type(g)?g:[g];for(var c=0;c<g.length;++c){var h=g[c],f=h.inside,d=!!h.lookbehind,m=!!h.greedy,p=0,y=h.alias;if(m&&!h.pattern.global){var v=h.pattern.toString().match(/[imuy]*$/)[0];h.pattern=RegExp(h.pattern.source,v+"g")}h=h.pattern||h;for(var b=r,k=i;b<t.length;k+=t[b].length,++b){var w=t[b];if(t.length>e.length)return;if(!(w instanceof s)){h.lastIndex=0;var _=h.exec(w),P=1;if(!_&&m&&b!=t.length-1){if(h.lastIndex=k,_=h.exec(e),!_)break;for(var A=_.index+(d?_[1].length:0),j=_.index+_[0].length,x=b,O=k,S=t.length;S>x&&(j>O||!t[x].type&&!t[x-1].greedy);++x)O+=t[x].length,A>=O&&(++b,k=O);if(t[b]instanceof s||t[x-1].greedy)continue;P=x-b,w=e.slice(k,O),_.index-=k}if(_){d&&(p=_[1].length);var A=_.index+p,_=_[0].slice(p),j=A+_.length,N=w.slice(0,A),C=w.slice(j),E=[b,P];N&&(++b,k+=N.length,E.push(N));var I=new s(u,f?n.tokenize(_,f):_,y,_,m);if(E.push(I),C&&E.push(C),Array.prototype.splice.apply(t,E),1!=P&&n.matchGrammar(e,t,a,b,k,!0,u),l)break}else if(l)break}}}}},tokenize:function(e,t){var a=[e],r=t.rest;if(r){for(var i in r)t[i]=r[i];delete t.rest}return n.matchGrammar(e,a,t,0,0,!1),a},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var i={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("commentLine truncated
|
|
||||||
Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:/<!DOCTYPE[\s\S]+?>/i,cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\s\S])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\s\S]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
|
|
||||||
Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<style[\s\S]*?>)[\s\S]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
|
|
||||||
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
|
|
||||||
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,operator:/-[-=]?|\+[+=]?|!=?=?|<<?=?|>>?>?=?|=(?:==?|>)?|&[&=]?|\|[|=]?|\*\*?=?|\/=?|~|\^=?|%=?|\?|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[[^\]\r\n]+]|\\.|[^\/\\\[\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<script[\s\S]*?>)[\s\S]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript;
|
|
||||||
Prism.languages.apacheconf={comment:/#.*/,"directive-inline":{pattern:/^(\s*)\b(AcceptFilter|AcceptPathInfo|AccessFileName|Action|AddAlt|AddAltByEncoding|AddAltByType|AddCharset|AddDefaultCharset|AddDescription|AddEncoding|AddHandler|AddIcon|AddIconByEncoding|AddIconByType|AddInputFilter|AddLanguage|AddModuleInfo|AddOutputFilter|AddOutputFilterByType|AddType|Alias|AliasMatch|Allow|AllowCONNECT|AllowEncodedSlashes|AllowMethods|AllowOverride|AllowOverrideList|Anonymous|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail|AsyncRequestWorkerFactor|AuthBasicAuthoritative|AuthBasicFake|AuthBasicProvider|AuthBasicUseDigestAlgorithm|AuthDBDUserPWQuery|AuthDBDUserRealmQuery|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile|AuthDigestAlgorithm|AuthDigestDomain|AuthDigestNonceLifetime|AuthDigestProvider|AuthDigestQop|AuthDigestShmemSize|AuthFormAuthoritative|AuthFormBody|AuthFormDisableNoStore|AuthFormFakeBasicAuth|AuthFormLocation|AuthFormLoginRequiredLocation|AuthFormLoginSuccessLocation|AuthFormLogoutLocation|AuthFormMethod|AuthFormMimetype|AuthFormPassword|AuthFormProvider|AuthFormSitePassphrase|AuthFormSize|AuthFormUsername|AuthGroupFile|AuthLDAPAuthorizePrefix|AuthLDAPBindAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareAsUser|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPInitialBindAsUser|AuthLDAPInitialBindPattern|AuthLDAPMaxSubGroupDepth|AuthLDAPRemoteUserAttribute|AuthLDAPRemoteUserIsDN|AuthLDAPSearchAsUser|AuthLDAPSubGroupAttribute|AuthLDAPSubGroupClass|AuthLDAPUrl|AuthMerging|AuthName|AuthnCacheContext|AuthnCacheEnable|AuthnCacheProvideFor|AuthnCacheSOCache|AuthnCacheTimeout|AuthnzFcgiCheckAuthnProvider|AuthnzFcgiDefineProvider|AuthType|AuthUserFile|AuthzDBDLoginToReferer|AuthzDBDQuery|AuthzDBDRedirectQuery|AuthzDBMType|AuthzSendForbiddenOnFailure|BalancerGrowth|BalancerInherit|BalancerMember|BalancerPersist|BrowserMatch|BrowserMatchNoCase|BufferedLogs|BufferSize|CacheDefaultExpire|CacheDetailHeader|CacheDirLength|CacheDirLevels|CacheDisable|CacheEnable|CacheFile|CacheHeader|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheIgnoreQueryString|CacheIgnoreURLSessionIdentifiers|CacheKeyBaseURL|CacheLastModifiedFactor|CacheLock|CacheLockMaxAge|CacheLockPath|CacheMaxExpire|CacheMaxFileSize|CacheMinExpire|CacheMinFileSize|CacheNegotiatedDocs|CacheQuickHandler|CacheReadSize|CacheReadTime|CacheRoot|CacheSocache|CacheSocacheMaxSize|CacheSocacheMaxTime|CacheSocacheMinTime|CacheSocacheReadSize|CacheSocacheReadTime|CacheStaleOnError|CacheStoreExpired|CacheStoreNoStore|CacheStorePrivate|CGIDScriptTimeout|CGIMapExtension|CharsetDefault|CharsetOptions|CharsetSourceEnc|CheckCaseOnly|CheckSpelling|ChrootDir|ContentDigest|CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking|CoreDumpDirectory|CustomLog|Dav|DavDepthInfinity|DavGenericLockDB|DavLockDB|DavMinTimeout|DBDExptime|DBDInitSQL|DBDKeep|DBDMax|DBDMin|DBDParams|DBDPersist|DBDPrepareSQL|DBDriver|DefaultIcon|DefaultLanguage|DefaultRuntimeDir|DefaultType|Define|DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateInflateLimitRequestBody|DeflateInflateRatioBurst|DeflateInflateRatioLimit|DeflateMemLevel|DeflateWindowSize|Deny|DirectoryCheckHandler|DirectoryIndex|DirectoryIndexRedirect|DirectorySlash|DocumentRoot|DTracePrivileges|DumpIOInput|DumpIOOutput|EnableExceptionHook|EnableMMAP|EnableSendfile|Error|ErrorDocument|ErrorLog|ErrorLogFormat|Example|ExpiresActive|ExpiresByType|ExpiresDefault|ExtendedStatus|ExtFilterDefine|ExtFilterOptions|FallbackResource|FileETag|FilterChain|FilterDeclare|FilterProtocol|FilterProvider|FilterTrace|ForceLanguagePriority|ForceType|ForensicLog|GprofDir|GracefulShutdownTimeout|Group|Header|HeaderName|HeartbeatAddress|HeartbeatListen|HeartbeatMaxServers|HeartbeatStorage|HeartbeatStorage|HostnameLookups|IdentityCheck|IdentityCheckTimeout|ImapBase|ImapDefault|ImapMenu|Include|IncludeOptional|IndexHeadInsert|IndexIgnore|IndexIgnoreReset|IndexOptions|IndexOrderDefault|IndexStyleSheet|InputSed|ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer|KeepAlive|KeepAliveTimeout|KeptBodySize|LanguagePriority|LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionPoolTTL|LDAPConnectionTimeout|LDAPLibraryDebug|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPReferralHopLimit|LDAPReferrals|LDAPRetries|LDAPRetryDelay|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTimeout|LDAPTrustedClientCert|LDAPTrustedGlobalCert|LDAPTrustedMode|LDAPVerifyServerCert|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|Listen|ListenBackLog|LoadFile|LoadModule|LogFormat|LogLevel|LogMessage|LuaAuthzProvider|LuaCodeCache|LuaHookAccessChecker|LuaHookAuthChecker|LuaHookCheckUserID|LuaHookFixups|LuaHookInsertFilter|LuaHookLog|LuaHookMapToStorage|LuaHookTranslateName|LuaHookTypeChecker|LuaInherit|LuaInputFilter|LLine truncated
|
|
||||||
Prism.languages.c=Prism.languages.extend("clike",{keyword:/\b(_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0},directive:{pattern:/(#\s*)\b(define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,lookbehind:!0,alias:"keyword"}}},constant:/\b(__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"];
|
|
||||||
!function(e){var t={variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b-?(?:0x[\dA-Fa-f]+|\d*\.?\d+(?:[Ee]-?\d+)?)\b/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\([^)]+\)|`[^`]+`/,inside:{variable:/^\$\(|^`|\)$|`$/}},/\$(?:[a-z0-9_#\?\*!@]+|\{[^}]+\})/i]};e.languages.bash={shebang:{pattern:/^#!\s*\/bin\/bash|^#!\s*\/bin\/sh/,alias:"important"},comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},string:[{pattern:/((?:^|[^<])<<\s*)(?:"|')?(\w+?)(?:"|')?\s*\r?\n(?:[\s\S])*?\r?\n\2/g,lookbehind:!0,greedy:!0,inside:t},{pattern:/(["'])(?:\\\\|\\?[^\\])*?\1/g,greedy:!0,inside:t}],variable:t.variable,"function":{pattern:/(^|\s|;|\||&)(?:alias|apropos|apt-get|aptitude|aspell|awk|basename|bash|bc|bg|builtin|bzip2|cal|cat|cd|cfdisk|chgrp|chmod|chown|chroot|chkconfig|cksum|clear|cmp|comm|command|cp|cron|crontab|csplit|cut|date|dc|dd|ddrescue|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|enable|env|ethtool|eval|exec|expand|expect|export|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|getopts|git|grep|groupadd|groupdel|groupmod|groups|gzip|hash|head|help|hg|history|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|jobs|join|kill|killall|less|link|ln|locate|logname|logout|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|make|man|mkdir|mkfifo|mkisofs|mknod|more|most|mount|mtools|mtr|mv|mmv|nano|netstat|nice|nl|nohup|notify-send|npm|nslookup|open|op|passwd|paste|pathchk|ping|pkill|popd|pr|printcap|printenv|printf|ps|pushd|pv|pwd|quota|quotacheck|quotactl|ram|rar|rcp|read|readarray|readonly|reboot|rename|renice|remsync|rev|rm|rmdir|rsync|screen|scp|sdiff|sed|seq|service|sftp|shift|shopt|shutdown|sleep|slocate|sort|source|split|ssh|stat|strace|su|sudo|sum|suspend|sync|tail|tar|tee|test|time|timeout|times|touch|top|traceroute|trap|tr|tsort|tty|type|ulimit|umask|umount|unalias|uname|unexpand|uniq|units|unrar|unshar|uptime|useradd|userdel|usermod|users|uuencode|uudecode|v|vdir|vi|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yes|zip)(?=$|\s|;|\||&)/,lookbehind:!0},keyword:{pattern:/(^|\s|;|\||&)(?:let|:|\.|if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)(?=$|\s|;|\||&)/,lookbehind:!0},"boolean":{pattern:/(^|\s|;|\||&)(?:true|false)(?=$|\s|;|\||&)/,lookbehind:!0},operator:/&&?|\|\|?|==?|!=?|<<<?|>>|<=?|>=?|=~/,punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];]/};var a=t.variable[1].inside;a["function"]=e.languages.bash["function"],a.keyword=e.languages.bash.keyword,a.boolean=e.languages.bash.boolean,a.operator=e.languages.bash.operator,a.punctuation=e.languages.bash.punctuation}(Prism);
|
|
||||||
!function(e){var r=/%%?[~:\w]+%?|!\S+!/,t={pattern:/\/[a-z?]+(?=[ :]|$):?|-[a-z]\b|--[a-z-]+\b/im,alias:"attr-name",inside:{punctuation:/:/}},n=/"[^"]*"/,i=/(?:\b|-)\d+\b/;e.languages.batch={comment:[/^::.*/m,{pattern:/((?:^|[&(])[ \t]*)rem\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0}],label:{pattern:/^:.*/m,alias:"property"},command:[{pattern:/((?:^|[&(])[ \t]*)for(?: ?\/[a-z?](?:[ :](?:"[^"]*"|\S+))?)* \S+ in \([^)]+\) do/im,lookbehind:!0,inside:{keyword:/^for\b|\b(?:in|do)\b/i,string:n,parameter:t,variable:r,number:i,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*)if(?: ?\/[a-z?](?:[ :](?:"[^"]*"|\S+))?)* (?:not )?(?:cmdextversion \d+|defined \w+|errorlevel \d+|exist \S+|(?:"[^"]*"|\S+)?(?:==| (?:equ|neq|lss|leq|gtr|geq) )(?:"[^"]*"|\S+))/im,lookbehind:!0,inside:{keyword:/^if\b|\b(?:not|cmdextversion|defined|errorlevel|exist)\b/i,string:n,parameter:t,variable:r,number:i,operator:/\^|==|\b(?:equ|neq|lss|leq|gtr|geq)\b/i}},{pattern:/((?:^|[&()])[ \t]*)else\b/im,lookbehind:!0,inside:{keyword:/^else\b/i}},{pattern:/((?:^|[&(])[ \t]*)set(?: ?\/[a-z](?:[ :](?:"[^"]*"|\S+))?)* (?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^set\b/i,string:n,parameter:t,variable:[r,/\w+(?=(?:[*\/%+\-&^|]|<<|>>)?=)/],number:i,operator:/[*\/%+\-&^|]=?|<<=?|>>=?|[!~_=]/,punctuation:/[()',]/}},{pattern:/((?:^|[&(])[ \t]*@?)\w+\b(?:[^^&)\r\n]|\^(?:\r\n|[\s\S]))*/im,lookbehind:!0,inside:{keyword:/^\w+\b/i,string:n,parameter:t,label:{pattern:/(^\s*):\S+/m,lookbehind:!0,alias:"property"},variable:r,number:i,operator:/\^/}}],operator:/[&@]/,punctuation:/[()']/}}(Prism);
|
|
||||||
Prism.languages.cpp=Prism.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),Prism.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}});
|
|
||||||
Prism.languages.csharp=Prism.languages.extend("clike",{keyword:/\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,string:[{pattern:/@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,greedy:!0},{pattern:/("|')(\\?.)*?\1/,greedy:!0}],number:/\b-?(0x[\da-f]+|\d*\.?\d+f?)\b/i}),Prism.languages.insertBefore("csharp","keyword",{"generic-method":{pattern:/[a-z0-9_]+\s*<[^>\r\n]+?>\s*(?=\()/i,alias:"function",inside:{keyword:Prism.languages.csharp.keyword,punctuation:/[<>(),.:]/}},preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(\s*#)\b(define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});
|
|
||||||
!function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#(?!\{[^\r\n]*?\}).*/,/^=begin(?:\r?\n|\r)(?:.*(?:\r?\n|\r))*?=end/m],keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.util.clone(e.languages.ruby)}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,symbol:/:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.insertBefore("ruby","number",{builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,greedy:!0,inside:{interpolation:n}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0,inside:{interpolation:n}},{pattern:/("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,greedy:!0,inside:{interpolation:n}}]}(Prism);
|
|
||||||
Prism.languages.css.selector={pattern:/[^\{\}\s][^\{\}]*(?=\s*\{)/,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+(?:\(.*\))?/,"class":/\.[-:\.\w]+/,id:/#[-:\.\w]+/,attribute:/\[[^\]]+\]/}},Prism.languages.insertBefore("css","function",{hexcode:/#[\da-f]{3,8}/i,entity:/\\[\da-f]{1,8}/i,number:/[\d%\.]+/});
|
|
||||||
var _django_template={property:{pattern:/(?:{{|{%)[\s\S]*?(?:%}|}})/g,greedy:!0,inside:{string:{pattern:/("|')(?:\\\\|\\?[^\\\r\n])*?\1/,greedy:!0},keyword:/\b(?:\||load|verbatim|widthratio|ssi|firstof|for|url|ifchanged|csrf_token|lorem|ifnotequal|autoescape|now|templatetag|debug|cycle|ifequal|regroup|comment|filter|endfilter|if|spaceless|with|extends|block|include|else|empty|endif|endfor|as|endblock|endautoescape|endverbatim|trans|endtrans|[Tt]rue|[Ff]alse|[Nn]one|in|is|static|macro|endmacro|call|endcall|set|endset|raw|endraw)\b/,operator:/[-+=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,"function":/\b(?:_|abs|add|addslashes|attr|batch|callable|capfirst|capitalize|center|count|cut|d|date|default|default_if_none|defined|dictsort|dictsortreversed|divisibleby|e|equalto|escape|escaped|escapejs|even|filesizeformat|first|float|floatformat|force_escape|forceescape|format|get_digit|groupby|indent|int|iriencode|iterable|join|last|length|length_is|linebreaks|linebreaksbr|linenumbers|list|ljust|lower|make_list|map|mapping|number|odd|phone2numeric|pluralize|pprint|random|reject|rejectattr|removetags|replace|reverse|rjust|round|safe|safeseq|sameas|select|selectattr|sequence|slice|slugify|sort|string|stringformat|striptags|sum|time|timesince|timeuntil|title|trim|truncate|truncatechars|truncatechars_html|truncatewords|truncatewords_html|undefined|unordered_list|upper|urlencode|urlize|urlizetrunc|wordcount|wordwrap|xmlattr|yesno)\b/,important:/\b-?\d+(?:\.\d+)?\b/,variable:/\b\w+?\b/,punctuation:/[[\];(),.:]/}}};Prism.languages.django=Prism.languages.extend("markup",{comment:/(?:<!--|{#)[\s\S]*?(?:#}|-->)/}),Prism.languages.django.tag.pattern=/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\s\S])*\1|[^>=]+))?)*\s*\/?>/i,Prism.languages.insertBefore("django","entity",_django_template),Prism.languages.insertBefore("inside","tag",_django_template,Prism.languages.django.tag),Prism.languages.javascript&&(Prism.languages.insertBefore("inside","string",_django_template,Prism.languages.django.script),Prism.languages.django.script.inside.string.inside=_django_template),Prism.languages.css&&(Prism.languages.insertBefore("inside","atrule",{tag:_django_template.property},Prism.languages.django.style),Prism.languages.django.style.inside.string.inside=_django_template),Prism.languages.jinja2=Prism.languages.django;
|
|
||||||
Prism.languages.docker={keyword:{pattern:/(^\s*)(?:ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|ONBUILD|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)(?=\s)/im,lookbehind:!0},string:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*?\1/,comment:/#.*/,punctuation:/---|\.\.\.|[:[\]{}\-,|>?]/},Prism.languages.dockerfile=Prism.languages.docker;
|
|
||||||
Prism.languages.git={comment:/^#.*/m,deleted:/^[-–].*/m,inserted:/^\+.*/m,string:/("|')(\\?.)*?\1/m,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s(--|-)\w+/m}},coord:/^@@.*@@$/m,commit_sha1:/^commit \w{40}$/m};
|
|
||||||
Prism.languages.http={"request-line":{pattern:/^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b\shttps?:\/\/\S+\sHTTP\/[0-9.]+/m,inside:{property:/^(POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b/,"attr-name":/:\w+/}},"response-status":{pattern:/^HTTP\/1.[01] \d+.*/m,inside:{property:{pattern:/(^HTTP\/1.[01] )\d+.*/i,lookbehind:!0}}},"header-name":{pattern:/^[\w-]+:(?=.)/m,alias:"keyword"}};var httpLanguages={"application/json":Prism.languages.javascript,"application/xml":Prism.languages.markup,"text/xml":Prism.languages.markup,"text/html":Prism.languages.markup};for(var contentType in httpLanguages)if(httpLanguages[contentType]){var options={};options[contentType]={pattern:new RegExp("(content-type:\\s*"+contentType+"[\\w\\W]*?)(?:\\r?\\n|\\r){2}[\\w\\W]*","i"),lookbehind:!0,inside:{rest:httpLanguages[contentType]}},Prism.languages.insertBefore("http","header-name",options)};
|
|
||||||
Prism.languages.ini={comment:/^[ \t]*;.*$/m,selector:/^[ \t]*\[.*?\]/m,constant:/^[ \t]*[^\s=]+?(?=[ \t]*=)/m,"attr-value":{pattern:/=.*/,inside:{punctuation:/^[=]/}}};
|
|
||||||
Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,operator:{pattern:/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,lookbehind:!0}}),Prism.languages.insertBefore("java","function",{annotation:{alias:"punctuation",pattern:/(^|[^.])@\w+/,lookbehind:!0}});
|
|
||||||
Prism.languages.json={property:/"(?:\\.|[^\\"])*"(?=\s*:)/gi,string:/"(?!:)(?:\\.|[^\\"])*"(?!:)/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee][+-]?\d+)?)\b/g,punctuation:/[{}[\]);,]/g,operator:/:/g,"boolean":/\b(true|false)\b/gi,"null":/\bnull\b/gi},Prism.languages.jsonp=Prism.languages.json;
|
|
||||||
!function(a){var e=/\\([^a-z()[\]]|[a-z\*]+)/i,n={"equation-command":{pattern:e,alias:"regex"}};a.languages.latex={comment:/%.*/m,cdata:{pattern:/(\\begin\{((?:verbatim|lstlisting)\*?)\})([\s\S]*?)(?=\\end\{\2\})/,lookbehind:!0},equation:[{pattern:/\$(?:\\?[\s\S])*?\$|\\\((?:\\?[\s\S])*?\\\)|\\\[(?:\\?[\s\S])*?\\\]/,inside:n,alias:"string"},{pattern:/(\\begin\{((?:equation|math|eqnarray|align|multline|gather)\*?)\})([\s\S]*?)(?=\\end\{\2\})/,lookbehind:!0,inside:n,alias:"string"}],keyword:{pattern:/(\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\[[^\]]+\])?\{)[^}]+(?=\})/,lookbehind:!0},url:{pattern:/(\\url\{)[^}]+(?=\})/,lookbehind:!0},headline:{pattern:/(\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\}(?:\[[^\]]+\])?)/,lookbehind:!0,alias:"class-name"},"function":{pattern:e,alias:"selector"},punctuation:/[[\]{}&]/}}(Prism);
|
|
||||||
Prism.languages.less=Prism.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-]+?(?:\([^{}]+\)|[^(){};])*?(?=\s*\{)/i,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\([^{}]*\)|[^{};@])*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i,punctuation:/[{}();:,]/,operator:/[+\-*\/]/}),Prism.languages.insertBefore("less","punctuation",{"function":Prism.languages.less.function}),Prism.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-]+.*?(?=[(;])/,lookbehind:!0,alias:"function"}});
|
|
||||||
Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,"function":/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/};
|
|
||||||
Prism.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|.)*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},builtin:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,symbol:{pattern:/^[^:=\r\n]+(?=\s*:(?!=))/m,inside:{variable:/\$+(?:[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:[/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,{pattern:/(\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \t])/,lookbehind:!0}],operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/};
|
|
||||||
Prism.languages.markdown=Prism.languages.extend("markup",{}),Prism.languages.insertBefore("markdown","prolog",{blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},code:[{pattern:/^(?: {4}|\t).+/m,alias:"keyword"},{pattern:/``.+?``|`[^`\n]+`/,alias:"keyword"}],title:[{pattern:/\w+.*(?:\r?\n|\r)(?:==+|--+)/,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#+.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])([\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:/(^|[^\\])(\*\*|__)(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^\*\*|^__|\*\*$|__$/}},italic:{pattern:/(^|[^\\])([*_])(?:(?:\r?\n|\r)(?!\r?\n|\r)|.)+?\2/,lookbehind:!0,inside:{punctuation:/^[*_]|[*_]$/}},url:{pattern:/!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,inside:{variable:{pattern:/(!?\[)[^\]]+(?=\]$)/,lookbehind:!0},string:{pattern:/"(?:\\.|[^"\\])*"(?=\)$)/}}}}),Prism.languages.markdown.bold.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.italic.inside.url=Prism.util.clone(Prism.languages.markdown.url),Prism.languages.markdown.bold.inside.italic=Prism.util.clone(Prism.languages.markdown.italic),Prism.languages.markdown.italic.inside.bold=Prism.util.clone(Prism.languages.markdown.bold);
|
|
||||||
Prism.languages.nginx=Prism.languages.extend("clike",{comment:{pattern:/(^|[^"{\\])#.*/,lookbehind:!0},keyword:/\b(?:CONTENT_|DOCUMENT_|GATEWAY_|HTTP_|HTTPS|if_not_empty|PATH_|QUERY_|REDIRECT_|REMOTE_|REQUEST_|SCGI|SCRIPT_|SERVER_|http|server|events|location|include|accept_mutex|accept_mutex_delay|access_log|add_after_body|add_before_body|add_header|addition_types|aio|alias|allow|ancient_browser|ancient_browser_value|auth|auth_basic|auth_basic_user_file|auth_http|auth_http_header|auth_http_timeout|autoindex|autoindex_exact_size|autoindex_localtime|break|charset|charset_map|charset_types|chunked_transfer_encoding|client_body_buffer_size|client_body_in_file_only|client_body_in_single_buffer|client_body_temp_path|client_body_timeout|client_header_buffer_size|client_header_timeout|client_max_body_size|connection_pool_size|create_full_put_path|daemon|dav_access|dav_methods|debug_connection|debug_points|default_type|deny|devpoll_changes|devpoll_events|directio|directio_alignment|disable_symlinks|empty_gif|env|epoll_events|error_log|error_page|expires|fastcgi_buffer_size|fastcgi_buffers|fastcgi_busy_buffers_size|fastcgi_cache|fastcgi_cache_bypass|fastcgi_cache_key|fastcgi_cache_lock|fastcgi_cache_lock_timeout|fastcgi_cache_methods|fastcgi_cache_min_uses|fastcgi_cache_path|fastcgi_cache_purge|fastcgi_cache_use_stale|fastcgi_cache_valid|fastcgi_connect_timeout|fastcgi_hide_header|fastcgi_ignore_client_abort|fastcgi_ignore_headers|fastcgi_index|fastcgi_intercept_errors|fastcgi_keep_conn|fastcgi_max_temp_file_size|fastcgi_next_upstream|fastcgi_no_cache|fastcgi_param|fastcgi_pass|fastcgi_pass_header|fastcgi_read_timeout|fastcgi_redirect_errors|fastcgi_send_timeout|fastcgi_split_path_info|fastcgi_store|fastcgi_store_access|fastcgi_temp_file_write_size|fastcgi_temp_path|flv|geo|geoip_city|geoip_country|google_perftools_profiles|gzip|gzip_buffers|gzip_comp_level|gzip_disable|gzip_http_version|gzip_min_length|gzip_proxied|gzip_static|gzip_types|gzip_vary|if|if_modified_since|ignore_invalid_headers|image_filter|image_filter_buffer|image_filter_jpeg_quality|image_filter_sharpen|image_filter_transparency|imap_capabilities|imap_client_buffer|include|index|internal|ip_hash|keepalive|keepalive_disable|keepalive_requests|keepalive_timeout|kqueue_changes|kqueue_events|large_client_header_buffers|limit_conn|limit_conn_log_level|limit_conn_zone|limit_except|limit_rate|limit_rate_after|limit_req|limit_req_log_level|limit_req_zone|limit_zone|lingering_close|lingering_time|lingering_timeout|listen|location|lock_file|log_format|log_format_combined|log_not_found|log_subrequest|map|map_hash_bucket_size|map_hash_max_size|master_process|max_ranges|memcached_buffer_size|memcached_connect_timeout|memcached_next_upstream|memcached_pass|memcached_read_timeout|memcached_send_timeout|merge_slashes|min_delete_depth|modern_browser|modern_browser_value|mp4|mp4_buffer_size|mp4_max_buffer_size|msie_padding|msie_refresh|multi_accept|open_file_cache|open_file_cache_errors|open_file_cache_min_uses|open_file_cache_valid|open_log_file_cache|optimize_server_names|override_charset|pcre_jit|perl|perl_modules|perl_require|perl_set|pid|pop3_auth|pop3_capabilities|port_in_redirect|post_action|postpone_output|protocol|proxy|proxy_buffer|proxy_buffer_size|proxy_buffering|proxy_buffers|proxy_busy_buffers_size|proxy_cache|proxy_cache_bypass|proxy_cache_key|proxy_cache_lock|proxy_cache_lock_timeout|proxy_cache_methods|proxy_cache_min_uses|proxy_cache_path|proxy_cache_use_stale|proxy_cache_valid|proxy_connect_timeout|proxy_cookie_domain|proxy_cookie_path|proxy_headers_hash_bucket_size|proxy_headers_hash_max_size|proxy_hide_header|proxy_http_version|proxy_ignore_client_abort|proxy_ignore_headers|proxy_intercept_errors|proxy_max_temp_file_size|proxy_method|proxy_next_upstream|proxy_no_cache|proxy_pass|proxy_pass_error_message|proxy_pass_header|proxy_pass_request_body|proxy_pass_request_headers|proxy_read_timeout|proxy_redirect|proxy_redirect_errors|proxy_send_lowat|proxy_send_timeout|proxy_set_body|proxy_set_header|proxy_ssl_session_reuse|proxy_store|proxy_store_access|proxy_temp_file_write_size|proxy_temp_path|proxy_timeout|proxy_upstream_fail_timeout|proxy_upstream_max_fails|random_index|read_ahead|real_ip_header|recursive_error_pages|request_pool_size|reset_timedout_connection|resolver|resolver_timeout|return|rewrite|root|rtsig_overflow_events|rtsig_overflow_test|rtsig_overflow_threshold|rtsig_signo|satisfy|satisfy_any|secure_link_secret|send_lowat|send_timeout|sendfile|sendfile_max_chunk|server|server_name|server_name_in_redirect|server_names_hash_bucket_size|server_names_hash_max_size|server_tokens|set|set_real_ip_from|smtp_auth|smtp_capabilities|so_keepalive|source_charset|split_clients|ssi|ssi_silent_errors|ssi_types|ssi_value_length|ssl|ssl_certificate|ssl_certificate_key|ssl_ciphers|ssl_client_certificate|ssl_crl|ssl_dhparam|ssl_engine|ssl_prefer_server_ciphers|ssl_protocols|ssl_session_cache|ssl_session_timeout|ssl_verify_client|ssl_verify_depth|starttls|stubLine truncated
|
|
||||||
Prism.languages.php=Prism.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0}}),Prism.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),Prism.languages.insertBefore("php","keyword",{delimiter:{pattern:/\?>|<\?(?:php|=)?/i,alias:"important"},variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&/(?:<\?php|<\?)/gi.test(e.code)&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\s\S]*?(?:\?>|$)/gi,function(a){for(var n=e.tokenStack.length;-1!==e.backupCode.indexOf("___PHP"+n+"___");)++n;return e.tokenStack[n]=a,"___PHP"+n+"___"}),e.grammar=Prism.languages.markup)}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&e.backupCode&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language&&e.tokenStack){e.grammar=Prism.languages.php;for(var a=0,n=Object.keys(e.tokenStack);a<n.length;++a){var t=n[a],r=e.tokenStack[t];e.highlightedCode=e.highlightedCode.replace("___PHP"+t+"___",'<span class="token php language-php">'+Prism.highlight(r,e.grammar,"php").replace(/\$/g,"$$$$")+"</span>")}e.element.innerHTML=e.highlightedCode}}));
|
|
||||||
Prism.languages.insertBefore("php","variable",{"this":/\$this\b/,global:/\$(?:_(?:SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE)|GLOBALS|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/,scope:{pattern:/\b[\w\\]+::/,inside:{keyword:/(static|self|parent)/,punctuation:/(::|\\)/}}});
|
|
||||||
Prism.languages.powershell={comment:[{pattern:/(^|[^`])<#[\s\S]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*/,lookbehind:!0}],string:[{pattern:/"(`?[\s\S])*?"/,greedy:!0,inside:{"function":{pattern:/[^`]\$\(.*?\)/,inside:{}}}},{pattern:/'([^']|'')*'/,greedy:!0}],namespace:/\[[a-z][\s\S]*?\]/i,"boolean":/\$(true|false)\b/i,variable:/\$\w+\b/i,"function":[/\b(Add-(Computer|Content|History|Member|PSSnapin|Type)|Checkpoint-Computer|Clear-(Content|EventLog|History|Item|ItemProperty|Variable)|Compare-Object|Complete-Transaction|Connect-PSSession|ConvertFrom-(Csv|Json|StringData)|Convert-Path|ConvertTo-(Csv|Html|Json|Xml)|Copy-(Item|ItemProperty)|Debug-Process|Disable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Disconnect-PSSession|Enable-(ComputerRestore|PSBreakpoint|PSRemoting|PSSessionConfiguration)|Enter-PSSession|Exit-PSSession|Export-(Alias|Clixml|Console|Csv|FormatData|ModuleMember|PSSession)|ForEach-Object|Format-(Custom|List|Table|Wide)|Get-(Alias|ChildItem|Command|ComputerRestorePoint|Content|ControlPanelItem|Culture|Date|Event|EventLog|EventSubscriber|FormatData|Help|History|Host|HotFix|Item|ItemProperty|Job|Location|Member|Module|Process|PSBreakpoint|PSCallStack|PSDrive|PSProvider|PSSession|PSSessionConfiguration|PSSnapin|Random|Service|TraceSource|Transaction|TypeData|UICulture|Unique|Variable|WmiObject)|Group-Object|Import-(Alias|Clixml|Csv|LocalizedData|Module|PSSession)|Invoke-(Command|Expression|History|Item|RestMethod|WebRequest|WmiMethod)|Join-Path|Limit-EventLog|Measure-(Command|Object)|Move-(Item|ItemProperty)|New-(Alias|Event|EventLog|Item|ItemProperty|Module|ModuleManifest|Object|PSDrive|PSSession|PSSessionConfigurationFile|PSSessionOption|PSTransportOption|Service|TimeSpan|Variable|WebServiceProxy)|Out-(Default|File|GridView|Host|Null|Printer|String)|Pop-Location|Push-Location|Read-Host|Receive-(Job|PSSession)|Register-(EngineEvent|ObjectEvent|PSSessionConfiguration|WmiEvent)|Remove-(Computer|Event|EventLog|Item|ItemProperty|Job|Module|PSBreakpoint|PSDrive|PSSession|PSSnapin|TypeData|Variable|WmiObject)|Rename-(Computer|Item|ItemProperty)|Reset-ComputerMachinePassword|Resolve-Path|Restart-(Computer|Service)|Restore-Computer|Resume-(Job|Service)|Save-Help|Select-(Object|String|Xml)|Send-MailMessage|Set-(Alias|Content|Date|Item|ItemProperty|Location|PSBreakpoint|PSDebug|PSSessionConfiguration|Service|StrictMode|TraceSource|Variable|WmiInstance)|Show-(Command|ControlPanelItem|EventLog)|Sort-Object|Split-Path|Start-(Job|Process|Service|Sleep|Transaction)|Stop-(Computer|Job|Process|Service)|Suspend-(Job|Service)|Tee-Object|Test-(ComputerSecureChannel|Connection|ModuleManifest|Path|PSSessionConfigurationFile)|Trace-Command|Unblock-File|Undo-Transaction|Unregister-(Event|PSSessionConfiguration)|Update-(FormatData|Help|List|TypeData)|Use-Transaction|Wait-(Event|Job|Process)|Where-Object|Write-(Debug|Error|EventLog|Host|Output|Progress|Verbose|Warning))\b/i,/\b(ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i],keyword:/\b(Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,operator:{pattern:/(\W?)(!|-(eq|ne|gt|ge|lt|le|sh[lr]|not|b?(and|x?or)|(Not)?(Like|Match|Contains|In)|Replace|Join|is(Not)?|as)\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/},Prism.languages.powershell.string[0].inside.boolean=Prism.languages.powershell.boolean,Prism.languages.powershell.string[0].inside.variable=Prism.languages.powershell.variable,Prism.languages.powershell.string[0].inside.function.inside=Prism.util.clone(Prism.languages.powershell);
|
|
||||||
Prism.languages.properties={comment:/^[ \t]*[#!].*$/m,"attr-value":{pattern:/(^[ \t]*(?:\\(?:\r\n|[\s\S])|[^\\\s:=])+?(?: *[=:] *| ))(?:\\(?:\r\n|[\s\S])|.)+/m,lookbehind:!0},"attr-name":/^[ \t]*(?:\\(?:\r\n|[\s\S])|[^\\\s:=])+?(?= *[ =:]| )/m,punctuation:/[=:]/};
|
|
||||||
Prism.languages.python={"triple-quoted-string":{pattern:/"""[\s\S]+?"""|'''[\s\S]+?'''/,alias:"string"},comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},string:{pattern:/("|')(?:\\\\|\\?[^\\\r\n])*?\1/,greedy:!0},"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)[a-z0-9_]+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(?:True|False)\b/,number:/\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/};
|
|
||||||
!function(a){var e=a.util.clone(a.languages.javascript);a.languages.jsx=a.languages.extend("markup",e),a.languages.jsx.tag.pattern=/<\/?[\w\.:-]+\s*(?:\s+(?:[\w\.:-]+(?:=(?:("|')(\\?[\s\S])*?\1|[^\s'">=]+|(\{[\s\S]*?\})))?|\{\.{3}\w+\}))*\s*\/?>/i,a.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:('|")[\s\S]*?(\1)|[^\s>]+)/i,a.languages.insertBefore("inside","attr-name",{spread:{pattern:/\{\.{3}\w+\}/,inside:{punctuation:/\{|\}|\./,"attr-value":/\w+/}}},a.languages.jsx.tag);var s=a.util.clone(a.languages.jsx);delete s.punctuation,s=a.languages.insertBefore("jsx","operator",{punctuation:/=(?={)|[{}[\];(),.:]/},{jsx:s}),a.languages.insertBefore("inside","attr-value",{script:{pattern:/=(\{(?:\{[^}]*\}|[^}])+\})/i,inside:s,alias:"language-javascript"}},a.languages.jsx.tag)}(Prism);
|
|
||||||
Prism.languages.rest={table:[{pattern:/(\s*)(?:\+[=-]+)+\+(?:\r?\n|\r)(?:\1(?:[+|].+)+[+|](?:\r?\n|\r))+\1(?:\+[=-]+)+\+/,lookbehind:!0,inside:{punctuation:/\||(?:\+[=-]+)+\+/}},{pattern:/(\s*)(?:=+ +)+=+((?:\r?\n|\r)\1.+)+(?:\r?\n|\r)\1(?:=+ +)+=+(?=(?:\r?\n|\r){2}|\s*$)/,lookbehind:!0,inside:{punctuation:/[=-]+/}}],"substitution-def":{pattern:/(^\s*\.\. )\|(?:[^|\s](?:[^|]*[^|\s])?)\| [^:]+::/m,lookbehind:!0,inside:{substitution:{pattern:/^\|(?:[^|\s]|[^|\s][^|]*[^|\s])\|/,alias:"attr-value",inside:{punctuation:/^\||\|$/}},directive:{pattern:/( +)[^:]+::/,lookbehind:!0,alias:"function",inside:{punctuation:/::$/}}}},"link-target":[{pattern:/(^\s*\.\. )\[[^\]]+\]/m,lookbehind:!0,alias:"string",inside:{punctuation:/^\[|\]$/}},{pattern:/(^\s*\.\. )_(?:`[^`]+`|(?:[^:\\]|\\.)+):/m,lookbehind:!0,alias:"string",inside:{punctuation:/^_|:$/}}],directive:{pattern:/(^\s*\.\. )[^:]+::/m,lookbehind:!0,alias:"function",inside:{punctuation:/::$/}},comment:{pattern:/(^\s*\.\.)(?:(?: .+)?(?:(?:\r?\n|\r).+)+| .+)(?=(?:\r?\n|\r){2}|$)/m,lookbehind:!0},title:[{pattern:/^(([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])\2+)(?:\r?\n|\r).+(?:\r?\n|\r)\1$/m,inside:{punctuation:/^[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+|[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+$/,important:/.+/}},{pattern:/(^|(?:\r?\n|\r){2}).+(?:\r?\n|\r)([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])\2+(?=\r?\n|\r|$)/,lookbehind:!0,inside:{punctuation:/[!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]+$/,important:/.+/}}],hr:{pattern:/((?:\r?\n|\r){2})([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])\2{3,}(?=(?:\r?\n|\r){2})/,lookbehind:!0,alias:"punctuation"},field:{pattern:/(^\s*):[^:\r\n]+:(?= )/m,lookbehind:!0,alias:"attr-name"},"command-line-option":{pattern:/(^\s*)(?:[+-][a-z\d]|(?:\-\-|\/)[a-z\d-]+)(?:[ =](?:[a-z][a-z\d_-]*|<[^<>]+>))?(?:, (?:[+-][a-z\d]|(?:\-\-|\/)[a-z\d-]+)(?:[ =](?:[a-z][a-z\d_-]*|<[^<>]+>))?)*(?=(?:\r?\n|\r)? {2,}\S)/im,lookbehind:!0,alias:"symbol"},"literal-block":{pattern:/::(?:\r?\n|\r){2}([ \t]+).+(?:(?:\r?\n|\r)\1.+)*/,inside:{"literal-block-punctuation":{pattern:/^::/,alias:"punctuation"}}},"quoted-literal-block":{pattern:/::(?:\r?\n|\r){2}([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~]).*(?:(?:\r?\n|\r)\1.*)*/,inside:{"literal-block-punctuation":{pattern:/^(?:::|([!"#$%&'()*+,\-.\/:;<=>?@\[\\\]^_`{|}~])\1*)/m,alias:"punctuation"}}},"list-bullet":{pattern:/(^\s*)(?:[*+\-•‣⁃]|\(?(?:\d+|[a-z]|[ivxdclm]+)\)|(?:\d+|[a-z]|[ivxdclm]+)\.)(?= )/im,lookbehind:!0,alias:"punctuation"},"doctest-block":{pattern:/(^\s*)>>> .+(?:(?:\r?\n|\r).+)*/m,lookbehind:!0,inside:{punctuation:/^>>>/}},inline:[{pattern:/(^|[\s\-:\/'"<(\[{])(?::[^:]+:`.*?`|`.*?`:[^:]+:|(\*\*?|``?|\|)(?!\s).*?[^\s]\2(?=[\s\-.,:;!?\\\/'")\]}]|$))/m,lookbehind:!0,inside:{bold:{pattern:/(^\*\*).+(?=\*\*$)/,lookbehind:!0},italic:{pattern:/(^\*).+(?=\*$)/,lookbehind:!0},"inline-literal":{pattern:/(^``).+(?=``$)/,lookbehind:!0,alias:"symbol"},role:{pattern:/^:[^:]+:|:[^:]+:$/,alias:"function",inside:{punctuation:/^:|:$/}},"interpreted-text":{pattern:/(^`).+(?=`$)/,lookbehind:!0,alias:"attr-value"},substitution:{pattern:/(^\|).+(?=\|$)/,lookbehind:!0,alias:"attr-value"},punctuation:/\*\*?|``?|\|/}}],link:[{pattern:/\[[^\]]+\]_(?=[\s\-.,:;!?\\\/'")\]}]|$)/,alias:"string",inside:{punctuation:/^\[|\]_$/}},{pattern:/(?:\b[a-z\d](?:[_.:+]?[a-z\d]+)*_?_|`[^`]+`_?_|_`[^`]+`)(?=[\s\-.,:;!?\\\/'")\]}]|$)/i,alias:"string",inside:{punctuation:/^_?`|`$|`?_?_$/}}],punctuation:{pattern:/(^\s*)(?:\|(?= |$)|(?:---?|—|\.\.|__)(?= )|\.\.$)/m,lookbehind:!0}};
|
|
||||||
Prism.languages.rust={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:[{pattern:/b?r(#*)"(?:\\?.)*?"\1/,greedy:!0},{pattern:/b?("|')(?:\\?.)*?\1/,greedy:!0}],keyword:/\b(?:abstract|alignof|as|be|box|break|const|continue|crate|do|else|enum|extern|false|final|fn|for|if|impl|in|let|loop|match|mod|move|mut|offsetof|once|override|priv|pub|pure|ref|return|sizeof|static|self|struct|super|true|trait|type|typeof|unsafe|unsized|use|virtual|where|while|yield)\b/,attribute:{pattern:/#!?\[.+?\]/,greedy:!0,alias:"attr-name"},"function":[/[a-z0-9_]+(?=\s*\()/i,/[a-z0-9_]+!(?=\s*\(|\[)/i],"macro-rules":{pattern:/[a-z0-9_]+!/i,alias:"function"},number:/\b-?(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(\d(_?\d)*)?\.?\d(_?\d)*([Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64)?|f32|f64))?\b/,"closure-params":{pattern:/\|[^|]*\|(?=\s*[{-])/,inside:{punctuation:/[\|:,]/,operator:/[&*]/}},punctuation:/[{}[\];(),:]|\.+|->/,operator:/[-+*\/%!^=]=?|@|&[&=]?|\|[|=]?|<<?=?|>>?=?/};
|
|
||||||
!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t]+.+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var a=/((\$[-_\w]+)|(#\{\$[-_\w]+\}))/i,t=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:a,operator:t}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s]+.*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:a,operator:t,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,delete e.languages.sass.selector,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,?[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,?[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism);
|
|
||||||
Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-]+(?:\([^()]+\)|[^(])*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)*url(?=\()/i,selector:{pattern:/(?=\S)[^@;\{\}\(\)]?([^@;\{\}\(\)]|&|#\{\$[-_\w]+\})+(?=\s*\{(\}|\s|[^\}]+(:|\{)[^\}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-_\w]+/,variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|for|each|while|import|extend|debug|warn|mixin|include|function|return|content)/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.scss.property={pattern:/(?:[\w-]|\$[-_\w]+|#\{\$[-_\w]+\})+(?=\s*:)/i,inside:{variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}},Prism.languages.insertBefore("scss","important",{variable:/\$[-_\w]+|#\{\$[-_\w]+\}/}),Prism.languages.insertBefore("scss","function",{placeholder:{pattern:/%[-_\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},"boolean":/\b(?:true|false)\b/,"null":/\bnull\b/,operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.util.clone(Prism.languages.scss);
|
|
||||||
Prism.languages.scala=Prism.languages.extend("java",{keyword:/<-|=>|\b(?:abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|null|object|override|package|private|protected|return|sealed|self|super|this|throw|trait|try|type|val|var|while|with|yield)\b/,string:[{pattern:/"""[\s\S]*?"""/,greedy:!0},{pattern:/("|')(?:\\\\|\\?[^\\\r\n])*?\1/,greedy:!0}],builtin:/\b(?:String|Int|Long|Short|Byte|Boolean|Double|Float|Char|Any|AnyRef|AnyVal|Unit|Nothing)\b/,number:/\b(?:0x[\da-f]*\.?[\da-f]+|\d*\.?\d+e?\d*[dfl]?)\b/i,symbol:/'[^\d\s\\]\w*/}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala["function"];
|
|
||||||
Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},string:{pattern:/(^|[^@\\])("|')(?:\\?[\s\S])*?\2/,greedy:!0,lookbehind:!0},variable:/@[\w.$]+|@("|'|`)(?:\\?[\s\S])+?\1/,"function":/\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR VARYING|CHARACTER (?:SET|VARYING)|CHARSET|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|DATA(?:BASES?)?|DATE(?:TIME)?|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITER(?:S)?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE(?: PRECISION)?|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE(?:D BY)?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEYS?|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL(?: CHAR VARYING| CHARACTER(?: VARYING)?| VARCHAR)?|NATURAL|NCHAR(?: VARCHAR)?|NEXT|NO(?: SQL|CHECK|CYCLE)?|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READ(?:S SQL DATA|TEXT)?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURNS?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START(?:ING BY)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED BY|TEXT(?:SIZE)?|THEN|TIMESTAMP|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNPIVOT|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?)\b/i,"boolean":/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b-?(?:0x)?\d*\.?[\da-f]+\b/,operator:/[-+*\/=%^~]|&&?|\|?\||!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/};
|
|
||||||
Prism.languages.typescript=Prism.languages.extend("javascript",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield|false|true|module|declare|constructor|string|Function|any|number|boolean|Array|enum|symbol|namespace|abstract|require|type)\b/}),Prism.languages.ts=Prism.languages.typescript;
|
|
||||||
Prism.languages.vim={string:/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\r\n]|'')*'/,comment:/".*/,"function":/\w+(?=\()/,keyword:/\b(?:ab|abbreviate|abc|abclear|abo|aboveleft|al|all|arga|argadd|argd|argdelete|argdo|arge|argedit|argg|argglobal|argl|arglocal|ar|args|argu|argument|as|ascii|bad|badd|ba|ball|bd|bdelete|be|bel|belowright|bf|bfirst|bl|blast|bm|bmodified|bn|bnext|bN|bNext|bo|botright|bp|bprevious|brea|break|breaka|breakadd|breakd|breakdel|breakl|breaklist|br|brewind|bro|browse|bufdo|b|buffer|buffers|bun|bunload|bw|bwipeout|ca|cabbrev|cabc|cabclear|caddb|caddbuffer|cad|caddexpr|caddf|caddfile|cal|call|cat|catch|cb|cbuffer|cc|ccl|cclose|cd|ce|center|cex|cexpr|cf|cfile|cfir|cfirst|cgetb|cgetbuffer|cgete|cgetexpr|cg|cgetfile|c|change|changes|chd|chdir|che|checkpath|checkt|checktime|cla|clast|cl|clist|clo|close|cmapc|cmapclear|cnew|cnewer|cn|cnext|cN|cNext|cnf|cnfile|cNfcNfile|cnorea|cnoreabbrev|col|colder|colo|colorscheme|comc|comclear|comp|compiler|conf|confirm|con|continue|cope|copen|co|copy|cpf|cpfile|cp|cprevious|cq|cquit|cr|crewind|cuna|cunabbrev|cu|cunmap|cw|cwindow|debugg|debuggreedy|delc|delcommand|d|delete|delf|delfunction|delm|delmarks|diffg|diffget|diffoff|diffpatch|diffpu|diffput|diffsplit|diffthis|diffu|diffupdate|dig|digraphs|di|display|dj|djump|dl|dlist|dr|drop|ds|dsearch|dsp|dsplit|earlier|echoe|echoerr|echom|echomsg|echon|e|edit|el|else|elsei|elseif|em|emenu|endfo|endfor|endf|endfunction|endfun|en|endif|endt|endtry|endw|endwhile|ene|enew|ex|exi|exit|exu|exusage|f|file|files|filetype|fina|finally|fin|find|fini|finish|fir|first|fix|fixdel|fo|fold|foldc|foldclose|folddoc|folddoclosed|foldd|folddoopen|foldo|foldopen|for|fu|fun|function|go|goto|gr|grep|grepa|grepadd|ha|hardcopy|h|help|helpf|helpfind|helpg|helpgrep|helpt|helptags|hid|hide|his|history|ia|iabbrev|iabc|iabclear|if|ij|ijump|il|ilist|imapc|imapclear|in|inorea|inoreabbrev|isearch|isp|isplit|iuna|iunabbrev|iu|iunmap|j|join|ju|jumps|k|keepalt|keepj|keepjumps|kee|keepmarks|laddb|laddbuffer|lad|laddexpr|laddf|laddfile|lan|language|la|last|later|lb|lbuffer|lc|lcd|lch|lchdir|lcl|lclose|let|left|lefta|leftabove|lex|lexpr|lf|lfile|lfir|lfirst|lgetb|lgetbuffer|lgete|lgetexpr|lg|lgetfile|lgr|lgrep|lgrepa|lgrepadd|lh|lhelpgrep|l|list|ll|lla|llast|lli|llist|lmak|lmake|lm|lmap|lmapc|lmapclear|lnew|lnewer|lne|lnext|lN|lNext|lnf|lnfile|lNf|lNfile|ln|lnoremap|lo|loadview|loc|lockmarks|lockv|lockvar|lol|lolder|lop|lopen|lpf|lpfile|lp|lprevious|lr|lrewind|ls|lt|ltag|lu|lunmap|lv|lvimgrep|lvimgrepa|lvimgrepadd|lw|lwindow|mak|make|ma|mark|marks|mat|match|menut|menutranslate|mk|mkexrc|mks|mksession|mksp|mkspell|mkvie|mkview|mkv|mkvimrc|mod|mode|m|move|mzf|mzfile|mz|mzscheme|nbkey|new|n|next|N|Next|nmapc|nmapclear|noh|nohlsearch|norea|noreabbrev|nu|number|nun|nunmap|omapc|omapclear|on|only|o|open|opt|options|ou|ounmap|pc|pclose|ped|pedit|pe|perl|perld|perldo|po|pop|popu|popu|popup|pp|ppop|pre|preserve|prev|previous|p|print|P|Print|profd|profdel|prof|profile|promptf|promptfind|promptr|promptrepl|ps|psearch|pta|ptag|ptf|ptfirst|ptj|ptjump|ptl|ptlast|ptn|ptnext|ptN|ptNext|ptp|ptprevious|ptr|ptrewind|pts|ptselect|pu|put|pw|pwd|pyf|pyfile|py|python|qa|qall|q|quit|quita|quitall|r|read|rec|recover|redi|redir|red|redo|redr|redraw|redraws|redrawstatus|reg|registers|res|resize|ret|retab|retu|return|rew|rewind|ri|right|rightb|rightbelow|rub|ruby|rubyd|rubydo|rubyf|rubyfile|ru|runtime|rv|rviminfo|sal|sall|san|sandbox|sa|sargument|sav|saveas|sba|sball|sbf|sbfirst|sbl|sblast|sbm|sbmodified|sbn|sbnext|sbN|sbNext|sbp|sbprevious|sbr|sbrewind|sb|sbuffer|scripte|scriptencoding|scrip|scriptnames|se|set|setf|setfiletype|setg|setglobal|setl|setlocal|sf|sfind|sfir|sfirst|sh|shell|sign|sil|silent|sim|simalt|sla|slast|sl|sleep|sm|smagic|sm|smap|smapc|smapclear|sme|smenu|sn|snext|sN|sNext|sni|sniff|sno|snomagic|snor|snoremap|snoreme|snoremenu|sor|sort|so|source|spelld|spelldump|spe|spellgood|spelli|spellinfo|spellr|spellrepall|spellu|spellundo|spellw|spellwrong|sp|split|spr|sprevious|sre|srewind|sta|stag|startg|startgreplace|star|startinsert|startr|startreplace|stj|stjump|st|stop|stopi|stopinsert|sts|stselect|sun|sunhide|sunm|sunmap|sus|suspend|sv|sview|syncbind|t|tab|tabc|tabclose|tabd|tabdo|tabe|tabedit|tabf|tabfind|tabfir|tabfirst|tabl|tablast|tabm|tabmove|tabnew|tabn|tabnext|tabN|tabNext|tabo|tabonly|tabp|tabprevious|tabr|tabrewind|tabs|ta|tag|tags|tc|tcl|tcld|tcldo|tclf|tclfile|te|tearoff|tf|tfirst|th|throw|tj|tjump|tl|tlast|tm|tm|tmenu|tn|tnext|tN|tNext|to|topleft|tp|tprevious|tr|trewind|try|ts|tselect|tu|tu|tunmenu|una|unabbreviate|u|undo|undoj|undojoin|undol|undolist|unh|unhide|unlet|unlo|unlockvar|unm|unmap|up|update|verb|verbose|ve|version|vert|vertical|vie|view|vim|vimgrep|vimgrepa|vimgrepadd|vi|visual|viu|viusage|vmapc|vmapclear|vne|vnew|vs|vsplit|vu|vunmap|wa|wall|wh|while|winc|wincmd|windo|winp|winpos|win|winsize|wn|wnext|wN|wNext|wp|wprevious|wq|wqa|wqall|w|write|ws|wsverb|wv|wviminfo|X|xa|xall|x|xit|xm|xmap|xmapc|xmapclear|xme|xmenu|XMLent|XMLns|xn|xnoremap|xnoreme|xnoremenLine truncated
|
|
||||||
Prism.languages.wiki=Prism.languages.extend("markup",{"block-comment":{pattern:/(^|[^\\])\/\*[\s\S]*?\*\//,lookbehind:!0,alias:"comment"},heading:{pattern:/^(=+).+?\1/m,inside:{punctuation:/^=+|=+$/,important:/.+/}},emphasis:{pattern:/('{2,5}).+?\1/,inside:{"bold italic":{pattern:/(''''').+?(?=\1)/,lookbehind:!0},bold:{pattern:/(''')[^'](?:.*?[^'])?(?=\1)/,lookbehind:!0},italic:{pattern:/('')[^'](?:.*?[^'])?(?=\1)/,lookbehind:!0},punctuation:/^''+|''+$/}},hr:{pattern:/^-{4,}/m,alias:"punctuation"},url:[/ISBN +(?:97[89][ -]?)?(?:\d[ -]?){9}[\dx]\b|(?:RFC|PMID) +\d+/i,/\[\[.+?\]\]|\[.+?\]/],variable:[/__[A-Z]+__/,/\{{3}.+?\}{3}/,/\{\{.+?}}/],symbol:[/^#redirect/im,/~{3,5}/],"table-tag":{pattern:/((?:^|[|!])[|!])[^|\r\n]+\|(?!\|)/m,lookbehind:!0,inside:{"table-bar":{pattern:/\|$/,alias:"punctuation"},rest:Prism.languages.markup.tag.inside}},punctuation:/^(?:\{\||\|\}|\|-|[*#:;!|])|\|\||!!/m}),Prism.languages.insertBefore("wiki","tag",{nowiki:{pattern:/<(nowiki|pre|source)\b[\s\S]*?>[\s\S]*?<\/\1>/i,inside:{tag:{pattern:/<(?:nowiki|pre|source)\b[\s\S]*?>|<\/(?:nowiki|pre|source)>/i,inside:Prism.languages.markup.tag.inside}}}});
|
|
||||||
Prism.languages.yaml={scalar:{pattern:/([\-:]\s*(![^\s]+)?[ \t]*[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\3[^\r\n]+)*)/,lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:/(\s*(?:^|[:\-,[{\r\n?])[ \t]*(![^\s]+)?[ \t]*)[^\r\n{[\]},#\s]+?(?=\s*:\s)/,lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(\d{4}-\d\d?-\d\d?([tT]|[ \t]+)\d\d?:\d{2}:\d{2}(\.\d*)?[ \t]*(Z|[-+]\d\d?(:\d{2})?)?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(:\d{2}(\.\d*)?)?)(?=[ \t]*($|,|]|}))/m,lookbehind:!0,alias:"number"},"boolean":{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(true|false)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},"null":{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)(null|~)[ \t]*(?=$|,|]|})/im,lookbehind:!0,alias:"important"},string:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')(?=[ \t]*($|,|]|}))/m,lookbehind:!0,greedy:!0},number:{pattern:/([:\-,[{]\s*(![^\s]+)?[ \t]*)[+\-]?(0x[\da-f]+|0o[0-7]+|(\d+\.?\d*|\.?\d+)(e[\+\-]?\d+)?|\.inf|\.nan)[ \t]*(?=$|,|]|})/im,lookbehind:!0},tag:/![^\s]+/,important:/[&*][\w]+/,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./};
|
|
||||||
!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var e="line-numbers",t=function(e){var t=n(e),r=t["white-space"];if("pre-wrap"===r||"pre-line"===r){var s=e.querySelector("code"),l=e.querySelector(".line-numbers-rows"),a=e.querySelector(".line-numbers-sizer"),i=e.textContent.split("\n");a||(a=document.createElement("span"),a.className="line-numbers-sizer",s.appendChild(a)),a.style.display="block",i.forEach(function(e,t){a.textContent=e||"\n";var n=a.getBoundingClientRect().height;l.children[t].style.height=n+"px"}),a.textContent="",a.style.display="none"}},n=function(e){return e?window.getComputedStyle?getComputedStyle(e):e.currentStyle||null:null};window.addEventListener("resize",function(){Array.prototype.forEach.call(document.querySelectorAll("pre."+e),t)}),Prism.hooks.add("complete",function(e){if(e.code){var n=e.element.parentNode,r=/\s*\bline-numbers\b\s*/;if(n&&/pre/i.test(n.nodeName)&&(r.test(n.className)||r.test(e.element.className))&&!e.element.querySelector(".line-numbers-rows")){r.test(e.element.className)&&(e.element.className=e.element.className.replace(r," ")),r.test(n.className)||(n.className+=" line-numbers");var s,l=e.code.match(/\n(?!$)/g),a=l?l.length+1:1,i=new Array(a+1);i=i.join("<span></span>"),s=document.createElement("span"),s.setAttribute("aria-hidden","true"),s.className="line-numbers-rows",s.innerHTML=i,n.hasAttribute("data-start")&&(n.style.counterReset="linenumber "+(parseInt(n.getAttribute("data-start"),10)-1)),e.element.appendChild(s),t(n)}}})}}();
|
|
||||||
!function(){if(("undefined"==typeof self||self.Prism)&&("undefined"==typeof global||global.Prism)){var i=/\b([a-z]{3,7}:\/\/|tel:)[\w\-+%~\/.:#=?&]+/,n=/\b\S+@[\w.]+[a-z]{2}/,e=/\[([^\]]+)]\(([^)]+)\)/,t=["comment","url","attr-value","string"];Prism.plugins.autolinker={processGrammar:function(a){a&&!a["url-link"]&&(Prism.languages.DFS(a,function(a,r,l){t.indexOf(l)>-1&&"Array"!==Prism.util.type(r)&&(r.pattern||(r=this[a]={pattern:r}),r.inside=r.inside||{},"comment"==l&&(r.inside["md-link"]=e),"attr-value"==l?Prism.languages.insertBefore("inside","punctuation",{"url-link":i},r):r.inside["url-link"]=i,r.inside["email-link"]=n)}),a["url-link"]=i,a["email-link"]=n)}},Prism.hooks.add("before-highlight",function(i){Prism.plugins.autolinker.processGrammar(i.grammar)}),Prism.hooks.add("wrap",function(i){if(/-link$/.test(i.type)){i.tag="a";var n=i.content;if("email-link"==i.type&&0!=n.indexOf("mailto:"))n="mailto:"+n;else if("md-link"==i.type){var t=i.content.match(e);n=t[2],i.content=t[1]}i.attributes.href=n}try{i.content=decodeURIComponent(i.content)}catch(a){}})}}();
|
|
||||||
!function(){"undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(){var e={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(t){for(var s,a=t.getAttribute("data-src"),n=t,r=/\blang(?:uage)?-(?!\*)(\w+)\b/i;n&&!r.test(n.className);)n=n.parentNode;if(n&&(s=(t.className.match(r)||[,""])[1]),!s){var o=(a.match(/\.(\w+)$/)||[,""])[1];s=e[o]||o}var l=document.createElement("code");l.className="language-"+s,t.textContent="",l.textContent="Loading…",t.appendChild(l);var i=new XMLHttpRequest;i.open("GET",a,!0),i.onreadystatechange=function(){4==i.readyState&&(i.status<400&&i.responseText?(l.textContent=i.responseText,Prism.highlightElement(l)):l.textContent=i.status>=400?"✖ Error "+i.status+" while fetching file: "+i.statusText:"✖ Error: File does not exist or is empty")},i.send(null)})},document.addEventListener("DOMContentLoaded",self.Prism.fileHighlight))}();
|
|
||||||
!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var t=[],e={},n=function(){};Prism.plugins.toolbar={};var a=Prism.plugins.toolbar.registerButton=function(n,a){var o;o="function"==typeof a?a:function(t){var e;return"function"==typeof a.onClick?(e=document.createElement("button"),e.type="button",e.addEventListener("click",function(){a.onClick.call(this,t)})):"string"==typeof a.url?(e=document.createElement("a"),e.href=a.url):e=document.createElement("span"),e.textContent=a.text,e},t.push(e[n]=o)},o=Prism.plugins.toolbar.hook=function(a){var o=a.element.parentNode;if(o&&/pre/i.test(o.nodeName)&&!o.classList.contains("code-toolbar")){o.classList.add("code-toolbar");var r=document.createElement("div");r.classList.add("toolbar"),document.body.hasAttribute("data-toolbar-order")&&(t=document.body.getAttribute("data-toolbar-order").split(",").map(function(t){return e[t]||n})),t.forEach(function(t){var e=t(a);if(e){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(e),r.appendChild(n)}}),o.appendChild(r)}};a("label",function(t){var e=t.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&e.hasAttribute("data-label")){var n,a,o=e.getAttribute("data-label");try{a=document.querySelector("template#"+o)}catch(r){}return a?n=a.content:(e.hasAttribute("data-url")?(n=document.createElement("a"),n.href=e.getAttribute("data-url")):n=document.createElement("span"),n.textContent=o),n}}),Prism.hooks.add("complete",o)}}();
|
|
||||||
!function(){"undefined"!=typeof self&&self.Prism&&self.document&&Prism.languages.markup&&(Prism.plugins.UnescapedMarkup=!0,Prism.hooks.add("before-highlightall",function(e){e.selector+=", .lang-markup script[type='text/plain'], .language-markup script[type='text/plain'], script[type='text/plain'].lang-markup, script[type='text/plain'].language-markup"}),Prism.hooks.add("before-sanity-check",function(e){if("markup"==e.language){if(e.element.matches("script[type='text/plain']")){var t=document.createElement("code"),a=document.createElement("pre");return a.className=t.className=e.element.className,e.element.dataset&&Object.keys(e.element.dataset).forEach(function(t){Object.prototype.hasOwnProperty.call(e.element.dataset,t)&&(a.dataset[t]=e.element.dataset[t])}),e.code=e.code.replace(/<\/script(>|>)/gi,"</script>"),t.textContent=e.code,a.appendChild(t),e.element.parentNode.replaceChild(a,e.element),e.element=t,void 0}var a=e.element.parentNode;!e.code&&a&&"pre"==a.nodeName.toLowerCase()&&e.element.childNodes.length&&"#comment"==e.element.childNodes[0].nodeName&&(e.element.textContent=e.code=e.element.childNodes[0].textContent)}}))}();
|
|
||||||
!function(){"undefined"!=typeof self&&self.Prism&&self.document&&Prism.hooks.add("complete",function(e){if(e.code){var t=e.element.parentNode,a=/\s*\bcommand-line\b\s*/;if(t&&/pre/i.test(t.nodeName)&&(a.test(t.className)||a.test(e.element.className))&&!e.element.querySelector(".command-line-prompt")){a.test(e.element.className)&&(e.element.className=e.element.className.replace(a,"")),a.test(t.className)||(t.className+=" command-line");var n=function(e,a){return(t.getAttribute(e)||a).replace(/"/g,""")},s=new Array(1+e.code.split("\n").length),r=n("data-prompt","");if(""!==r)s=s.join('<span data-prompt="'+r+'"></span>');else{var l=n("data-user","user"),m=n("data-host","localhost");s=s.join('<span data-user="'+l+'" data-host="'+m+'"></span>')}var o=document.createElement("span");o.className="command-line-prompt",o.innerHTML=s;var i=t.getAttribute("data-output")||"";i=i.split(",");for(var c=0;c<i.length;c++){var p=i[c].split("-"),d=parseInt(p[0]),u=d;if(2===p.length&&(u=parseInt(p[1])),!isNaN(d)&&!isNaN(u))for(var f=d;u>=f&&f<=o.children.length;f++){var N=o.children[f-1];N.removeAttribute("data-user"),N.removeAttribute("data-host"),N.removeAttribute("data-prompt")}}e.element.innerHTML=o.outerHTML+e.element.innerHTML}}})}();
|
|
||||||
!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Show Languages plugin loaded before Toolbar plugin."),void 0;var e={html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",css:"CSS",clike:"C-like",javascript:"JavaScript",abap:"ABAP",actionscript:"ActionScript",apacheconf:"Apache Configuration",apl:"APL",applescript:"AppleScript",asciidoc:"AsciiDoc",aspnet:"ASP.NET (C#)",autoit:"AutoIt",autohotkey:"AutoHotkey",basic:"BASIC",csharp:"C#",cpp:"C++",coffeescript:"CoffeeScript","css-extras":"CSS Extras",django:"Django/Jinja2",fsharp:"F#",glsl:"GLSL",graphql:"GraphQL",http:"HTTP",inform7:"Inform 7",json:"JSON",latex:"LaTeX",livescript:"LiveScript",lolcode:"LOLCODE",matlab:"MATLAB",mel:"MEL",n4js:"N4JS",nasm:"NASM",nginx:"nginx",nsis:"NSIS",objectivec:"Objective-C",ocaml:"OCaml",opencl:"OpenCL",parigp:"PARI/GP",php:"PHP","php-extras":"PHP Extras",powershell:"PowerShell",properties:".properties",protobuf:"Protocol Buffers",jsx:"React JSX",renpy:"Ren'py",rest:"reST (reStructuredText)",sas:"SAS",sass:"Sass (Sass)",scss:"Sass (Scss)",sql:"SQL",typescript:"TypeScript",vbnet:"VB.Net",vhdl:"VHDL",vim:"vim",wiki:"Wiki markup",xojo:"Xojo (REALbasic)",yaml:"YAML"};Prism.plugins.toolbar.registerButton("show-language",function(t){var a=t.element.parentNode;if(a&&/pre/i.test(a.nodeName)){var s=a.getAttribute("data-language")||e[t.language]||t.language.substring(0,1).toUpperCase()+t.language.substring(1),r=document.createElement("span");return r.textContent=s,r}})}}();
|
|
||||||
!function(){if("undefined"!=typeof self&&self.Prism&&self.document){if(!Prism.plugins.toolbar)return console.warn("Copy to Clipboard plugin loaded before Toolbar plugin."),void 0;var o=window.Clipboard||void 0;o||"function"!=typeof require||(o=require("clipboard"));var e=[];if(!o){var t=document.createElement("script"),n=document.querySelector("head");t.onload=function(){if(o=window.Clipboard)for(;e.length;)e.pop()()},t.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.8/clipboard.min.js",n.appendChild(t)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(t){function n(){var e=new o(i,{text:function(){return t.code}});e.on("success",function(){i.textContent="Copied!",r()}),e.on("error",function(){i.textContent="Press Ctrl+C to copy",r()})}function r(){setTimeout(function(){i.textContent="Copy"},5e3)}var i=document.createElement("a");return i.textContent="Copy",o?n():e.push(n),i})}}();
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
|
|
||||||
# For additional information regarding the format and rule options, please see:
|
|
||||||
# https://github.com/browserslist/browserslist#queries
|
|
||||||
#
|
|
||||||
# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
|
|
||||||
|
|
||||||
> 0.5%
|
|
||||||
last 2 versions
|
|
||||||
Firefox ESR
|
|
||||||
not dead
|
|
||||||
not IE 9-11
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// The file contents for the current environment will overwrite these during build.
|
|
||||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
|
||||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
|
||||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
|
||||||
|
|
||||||
export const environment = {
|
|
||||||
production: false,
|
|
||||||
apiUrl: 'http://192.168.0.153:8445',
|
|
||||||
appVersion: '1.0.1',
|
|
||||||
title: 'Intégration'
|
|
||||||
};
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
export const environment = {
|
|
||||||
production: true,
|
|
||||||
apiUrl: 'https://176.188.217.1:54444',
|
|
||||||
appVersion: '1.0.1',
|
|
||||||
title: ''
|
|
||||||
};
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
// The file contents for the current environment will overwrite these during build.
|
|
||||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
|
||||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
|
||||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
|
||||||
|
|
||||||
export const environment = {
|
|
||||||
production: false,
|
|
||||||
apiUrl: 'http://localhost:8080',
|
|
||||||
// apiUrl: 'http://192.168.0.153:8445',
|
|
||||||
appVersion: '1.0.1',
|
|
||||||
title: 'Développement'
|
|
||||||
};
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,17 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Codiki</title>
|
|
||||||
<meta charset="utf-8"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<base href="/" />
|
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.png" />
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
|
||||||
<link href="./assets/css/prism.css" rel="stylesheet" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<app-root></app-root>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.8/clipboard.min.js"></script>
|
|
||||||
<script type="text/javascript" src="./assets/js/prism.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
// Karma configuration file, see link for more information
|
|
||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
|
||||||
|
|
||||||
module.exports = function (config) {
|
|
||||||
config.set({
|
|
||||||
basePath: '',
|
|
||||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
|
||||||
plugins: [
|
|
||||||
require('karma-jasmine'),
|
|
||||||
require('karma-chrome-launcher'),
|
|
||||||
require('karma-jasmine-html-reporter'),
|
|
||||||
require('karma-coverage-istanbul-reporter'),
|
|
||||||
require('@angular-devkit/build-angular/plugins/karma')
|
|
||||||
],
|
|
||||||
client: {
|
|
||||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
|
||||||
},
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
dir: require('path').join(__dirname, '../coverage'),
|
|
||||||
reports: ['html', 'lcovonly'],
|
|
||||||
fixWebpackSourcePaths: true
|
|
||||||
},
|
|
||||||
reporters: ['progress', 'kjhtml'],
|
|
||||||
port: 9876,
|
|
||||||
colors: true,
|
|
||||||
logLevel: config.LOG_INFO,
|
|
||||||
autoWatch: true,
|
|
||||||
browsers: ['Chrome'],
|
|
||||||
singleRun: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { enableProdMode } from '@angular/core';
|
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
||||||
|
|
||||||
import { AppModule } from './app/app.module';
|
|
||||||
import { environment } from './environments/environment';
|
|
||||||
|
|
||||||
if (environment.production) {
|
|
||||||
enableProdMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
|
||||||
.catch(err => console.error(err));
|
|
||||||
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/**
|
|
||||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
|
||||||
* You can add your own extra polyfills to this file.
|
|
||||||
*
|
|
||||||
* This file is divided into 2 sections:
|
|
||||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
|
||||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
|
||||||
* file.
|
|
||||||
*
|
|
||||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
|
||||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
|
||||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
|
||||||
*
|
|
||||||
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* BROWSER POLYFILLS
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
|
||||||
// import 'core-js/es6/symbol';
|
|
||||||
// import 'core-js/es6/object';
|
|
||||||
// import 'core-js/es6/function';
|
|
||||||
// import 'core-js/es6/parse-int';
|
|
||||||
// import 'core-js/es6/parse-float';
|
|
||||||
// import 'core-js/es6/number';
|
|
||||||
// import 'core-js/es6/math';
|
|
||||||
// import 'core-js/es6/string';
|
|
||||||
// import 'core-js/es6/date';
|
|
||||||
// import 'core-js/es6/array';
|
|
||||||
// import 'core-js/es6/regexp';
|
|
||||||
// import 'core-js/es6/map';
|
|
||||||
// import 'core-js/es6/weak-map';
|
|
||||||
// import 'core-js/es6/set';
|
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
|
||||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
|
||||||
|
|
||||||
/** IE10 and IE11 requires the following for the Reflect API. */
|
|
||||||
// import 'core-js/es6/reflect';
|
|
||||||
|
|
||||||
|
|
||||||
/** Evergreen browsers require these. **/
|
|
||||||
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
|
|
||||||
import 'core-js/es7/reflect';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Web Animations `@angular/platform-browser/animations`
|
|
||||||
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
|
||||||
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
|
||||||
**/
|
|
||||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default, zone.js will patch all possible macroTask and DomEvents
|
|
||||||
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
|
||||||
// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
|
||||||
// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
|
||||||
|
|
||||||
/*
|
|
||||||
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
|
||||||
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
|
||||||
*/
|
|
||||||
// (window as any).__Zone_enable_cross_context_check = true;
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* Zone JS is required by default for Angular itself.
|
|
||||||
*/
|
|
||||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* APPLICATION IMPORTS
|
|
||||||
*/
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
|
||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
// 64px for the header and 15px for a litle margin.
|
|
||||||
padding-top: 90px;
|
|
||||||
padding-bottom: 30px;
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content:space-between;
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ***** Floating card button ***** */
|
|
||||||
.btn-card-floating {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 47px;
|
|
||||||
height: 47px;
|
|
||||||
margin: -23px 20px;
|
|
||||||
margin-left: auto;
|
|
||||||
line-height: 0;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 47px;
|
|
||||||
padding-left: 2px;
|
|
||||||
z-index: 1;
|
|
||||||
box-shadow: 0 5px 11px 0 rgba(0,0,0,.18), 0 4px 15px 0 rgba(0,0,0,.15);
|
|
||||||
background-color: #3f51b5;
|
|
||||||
transition: box-shadow 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-card-floating:hover {
|
|
||||||
box-shadow: 0 8px 17px 0 rgba(0,0,0,.2), 0 6px 20px 0 rgba(0,0,0,.19);
|
|
||||||
}
|
|
||||||
/* ***** End of floating card button ***** */
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
|
||||||
|
|
||||||
import 'zone.js/dist/zone-testing';
|
|
||||||
import { getTestBed } from '@angular/core/testing';
|
|
||||||
import {
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting
|
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
|
||||||
|
|
||||||
declare const require: any;
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
|
||||||
getTestBed().initTestEnvironment(
|
|
||||||
BrowserDynamicTestingModule,
|
|
||||||
platformBrowserDynamicTesting()
|
|
||||||
);
|
|
||||||
// Then we find all the tests.
|
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
|
||||||
// And load the modules.
|
|
||||||
context.keys().map(context);
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/app",
|
|
||||||
"types": []
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"test.ts",
|
|
||||||
"**/*.spec.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/spec",
|
|
||||||
"types": [
|
|
||||||
"jasmine",
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"test.ts",
|
|
||||||
"polyfills.ts"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"**/*.spec.ts",
|
|
||||||
"**/*.d.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../tslint.json",
|
|
||||||
"rules": {
|
|
||||||
"directive-selector": [
|
|
||||||
true,
|
|
||||||
"attribute",
|
|
||||||
"app",
|
|
||||||
"camelCase"
|
|
||||||
],
|
|
||||||
"component-selector": [
|
|
||||||
true,
|
|
||||||
"element",
|
|
||||||
"app",
|
|
||||||
"kebab-case"
|
|
||||||
],
|
|
||||||
"indent": [
|
|
||||||
true,
|
|
||||||
"tabs"
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"compileOnSave": false,
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": "./",
|
|
||||||
"outDir": "./dist/out-tsc",
|
|
||||||
"sourceMap": true,
|
|
||||||
"declaration": false,
|
|
||||||
"module": "es2015",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"target": "es5",
|
|
||||||
"typeRoots": [
|
|
||||||
"node_modules/@types"
|
|
||||||
],
|
|
||||||
"lib": [
|
|
||||||
"es2017",
|
|
||||||
"dom"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
{
|
|
||||||
"rulesDirectory": [
|
|
||||||
"node_modules/codelyzer"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"arrow-return-shorthand": true,
|
|
||||||
"callable-types": true,
|
|
||||||
"class-name": true,
|
|
||||||
"comment-format": [
|
|
||||||
true,
|
|
||||||
"check-space"
|
|
||||||
],
|
|
||||||
"curly": true,
|
|
||||||
"deprecation": {
|
|
||||||
"severity": "warn"
|
|
||||||
},
|
|
||||||
"eofline": true,
|
|
||||||
"forin": true,
|
|
||||||
"import-blacklist": [
|
|
||||||
true,
|
|
||||||
"rxjs/Rx"
|
|
||||||
],
|
|
||||||
"import-spacing": true,
|
|
||||||
"indent": [
|
|
||||||
true,
|
|
||||||
"spaces"
|
|
||||||
],
|
|
||||||
"interface-over-type-literal": true,
|
|
||||||
"label-position": true,
|
|
||||||
"max-line-length": [
|
|
||||||
true,
|
|
||||||
140
|
|
||||||
],
|
|
||||||
"member-access": false,
|
|
||||||
"member-ordering": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"order": [
|
|
||||||
"static-field",
|
|
||||||
"instance-field",
|
|
||||||
"static-method",
|
|
||||||
"instance-method"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"no-arg": true,
|
|
||||||
"no-bitwise": true,
|
|
||||||
"no-console": [
|
|
||||||
true,
|
|
||||||
"debug",
|
|
||||||
"info",
|
|
||||||
"time",
|
|
||||||
"timeEnd",
|
|
||||||
"trace"
|
|
||||||
],
|
|
||||||
"no-construct": true,
|
|
||||||
"no-debugger": true,
|
|
||||||
"no-duplicate-super": true,
|
|
||||||
"no-empty": false,
|
|
||||||
"no-empty-interface": true,
|
|
||||||
"no-eval": true,
|
|
||||||
"no-inferrable-types": [
|
|
||||||
true,
|
|
||||||
"ignore-params"
|
|
||||||
],
|
|
||||||
"no-misused-new": true,
|
|
||||||
"no-non-null-assertion": true,
|
|
||||||
"no-redundant-jsdoc": true,
|
|
||||||
"no-shadowed-variable": true,
|
|
||||||
"no-string-literal": false,
|
|
||||||
"no-string-throw": true,
|
|
||||||
"no-switch-case-fall-through": true,
|
|
||||||
"no-trailing-whitespace": true,
|
|
||||||
"no-unnecessary-initializer": true,
|
|
||||||
"no-unused-expression": true,
|
|
||||||
"no-use-before-declare": true,
|
|
||||||
"no-var-keyword": true,
|
|
||||||
"object-literal-sort-keys": false,
|
|
||||||
"one-line": [
|
|
||||||
true,
|
|
||||||
"check-open-brace",
|
|
||||||
"check-catch",
|
|
||||||
"check-else",
|
|
||||||
"check-whitespace"
|
|
||||||
],
|
|
||||||
"prefer-const": true,
|
|
||||||
"quotemark": [
|
|
||||||
true,
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"radix": true,
|
|
||||||
"semicolon": [
|
|
||||||
true,
|
|
||||||
"always"
|
|
||||||
],
|
|
||||||
"triple-equals": [
|
|
||||||
true,
|
|
||||||
"allow-null-check"
|
|
||||||
],
|
|
||||||
"typedef-whitespace": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"call-signature": "nospace",
|
|
||||||
"index-signature": "nospace",
|
|
||||||
"parameter": "nospace",
|
|
||||||
"property-declaration": "nospace",
|
|
||||||
"variable-declaration": "nospace"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"unified-signatures": true,
|
|
||||||
"variable-name": false,
|
|
||||||
"whitespace": [
|
|
||||||
true,
|
|
||||||
"check-branch",
|
|
||||||
"check-decl",
|
|
||||||
"check-operator",
|
|
||||||
"check-separator",
|
|
||||||
"check-type"
|
|
||||||
],
|
|
||||||
"no-output-on-prefix": true,
|
|
||||||
"use-input-property-decorator": true,
|
|
||||||
"use-output-property-decorator": true,
|
|
||||||
"use-host-property-decorator": true,
|
|
||||||
"no-input-rename": true,
|
|
||||||
"no-output-rename": true,
|
|
||||||
"use-life-cycle-interface": true,
|
|
||||||
"use-pipe-transform-interface": true,
|
|
||||||
"component-class-suffix": true,
|
|
||||||
"directive-class-suffix": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||