UNPKG

ngx-ice-tweet

Version:

tweeter component to show tweets by a hashtag given, it can be order by text, date, or user name

242 lines (234 loc) 19.6 kB
import { Injectable, NgModule, Component, EventEmitter, Input, Output, ViewEncapsulation, defineInjectable } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, HttpClientModule } from '@angular/common/http'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { FormsModule } from '@angular/forms'; import { MatCardModule, MatSelectModule } from '@angular/material'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class TweetService { constructor() { } } TweetService.decorators = [ { type: Injectable, args: [{ providedIn: 'root' },] } ]; /** @nocollapse */ TweetService.ctorParameters = () => []; /** @nocollapse */ TweetService.ngInjectableDef = defineInjectable({ factory: function TweetService_Factory() { return new TweetService(); }, token: TweetService, providedIn: "root" }); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const TweetConfig = { tokenUrl: 'https://api.twitter.com/oauth2/token', tweetSearchUrl: 'https://api.twitter.com/1.1/search/tweets.json' }; class TweetComponent { /** * @param {?} http */ constructor(http) { this.http = http; this.errorMesage = new EventEmitter(); this.filterBy = 'created_at'; this.filterOptions = ['created_at', 'text', 'user.name']; this._unsubscribeAll = new Subject(); } /** * @return {?} */ ngOnInit() { if (this.evalData()) { this.getToken(); } else { this.sendErrorMesage('No Public, Privite Key'); this.ngOnDestroy(); } } /** * @return {?} */ setFilterBy() { return this.tweets.sort((a, b) => a[this.filterBy] > b[this.filterBy] ? 1 : a[this.filterBy] === b[this.filterBy] ? 0 : -1); } /** * @private * @return {?} */ evalData() { return (this.keyPublic && this.keyPrivate && this.keyPublic !== null && this.keyPrivate !== null && this.keyPublic !== '' && this.keyPrivate !== ''); } /** * @private * @return {?} */ evaHash() { return (this.hashTag && this.hashTag !== null && this.hashTag !== ''); } /** * @private * @param {?} token * @return {?} */ evalToken(token) { return (token.token_type && token.access_token && token.token_type !== null && token.access_token !== null && token.token_type !== '' && token.access_token !== ''); } /** * @private * @return {?} */ getToken() { if (this.evaHash()) { /** @type {?} */ const basic = btoa(`${this.keyPublic}:${this.keyPrivate}`); /** @type {?} */ const headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': `Basic ${basic}` }); /** @type {?} */ const payload = new FormData(); payload.append('grant_type', 'client_credentials'); this.http.post(TweetConfig.tokenUrl, payload, { headers: headers }) .pipe(takeUntil(this._unsubscribeAll)) .subscribe(token => this.getTweetList(token), error => this.sendErrorMesage(error)); } else { this.sendErrorMesage('No HasgTag set For Searching'); } } /** * @private * @param {?} token * @return {?} */ getTweetList(token) { if (this.evalToken(token)) { /** @type {?} */ const headers = new HttpHeaders({ 'Authorization': `${token.token_type} ${token.access_token}` }); /** @type {?} */ const params = new HttpParams().set('q', `%23${this.hashTag}`); this.http.get(TweetConfig.tweetSearchUrl, { headers: headers, params: params }) .pipe(takeUntil(this._unsubscribeAll)) .subscribe(({ statuses }) => this.tweets = (/** @type {?} */ (statuses)), error => this.sendErrorMesage(error)); } else { this.sendErrorMesage('Error Tweeter Token'); } } /** * @private * @param {?} men * @return {?} */ sendErrorMesage(men) { this.errorMesage.emit(men); } /** * @return {?} */ ngOnDestroy() { this._unsubscribeAll.next(); this._unsubscribeAll.complete(); } } TweetComponent.decorators = [ { type: Component, args: [{ selector: 'tweet', template: `<div class="container" *ngIf="tweets && tweets.length > 0"> <div> <h4>filter by:</h4> <mat-form-field> <mat-select [(value)]="filterBy"> <mat-option *ngFor="let opt of filterOptions" value="opt">{{opt}}</mat-option> </mat-select> </mat-form-field> </div> <mat-card *ngFor="let tt of setFilterBy()" > <mat-card-header> <mat-card-title>{{tt.user.screen_name}}</mat-card-title> <mat-card-subtitle>@{{tt.user.name}}</mat-card-subtitle> </mat-card-header> <img matCardImage [src]="tt.user.profile_image_url"> <mat-card-content> {{tt.text}} </mat-card-content> <mat-card-actions align="start"> <!--<button mat-button (click)="onAction1">Action1</button>--> </mat-card-actions> <mat-card-footer> </mat-card-footer> </mat-card> </div>`, encapsulation: ViewEncapsulation.Native, styles: [` .container { width: 100%; margin: 2rem; display: flex; flex-direction: column; } mat-card { margin-bottom: 2rem; flex: 1 1 100%; }`] }] } ]; /** @nocollapse */ TweetComponent.ctorParameters = () => [ { type: HttpClient } ]; TweetComponent.propDecorators = { keyPublic: [{ type: Input }], keyPrivate: [{ type: Input }], hashTag: [{ type: Input }], errorMesage: [{ type: Output }] }; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class TweetModule { } TweetModule.decorators = [ { type: NgModule, args: [{ declarations: [TweetComponent], imports: [ BrowserModule, HttpClientModule, BrowserAnimationsModule, MatCardModule, MatSelectModule, FormsModule ], exports: [TweetComponent] },] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { TweetService, TweetComponent, TweetModule }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWljZS10d2VldC5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmd4LWljZS10d2VldC9saWIvdHdlZXQuc2VydmljZS50cyIsIm5nOi8vbmd4LWljZS10d2VldC9saWIvdHdlZXQuY29tcG9uZW50LnRzIiwibmc6Ly9uZ3gtaWNlLXR3ZWV0L2xpYi90d2VldC5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUd2VldFNlcnZpY2Uge1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG59XG4iLCJpbXBvcnQge0NvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgVmlld0VuY2Fwc3VsYXRpb259IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtIdHRwQ2xpZW50LCBIdHRwSGVhZGVycywgSHR0cFBhcmFtc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHtTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7dGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmNvbnN0IFR3ZWV0Q29uZmlnID0ge1xuICB0b2tlblVybDogJ2h0dHBzOi8vYXBpLnR3aXR0ZXIuY29tL29hdXRoMi90b2tlbicsXG4gIHR3ZWV0U2VhcmNoVXJsOiAnaHR0cHM6Ly9hcGkudHdpdHRlci5jb20vMS4xL3NlYXJjaC90d2VldHMuanNvbidcbn07XG5cbmludGVyZmFjZSBUb2tlbiB7XG4gIHRva2VuX3R5cGU6IHN0cmluZztcbiAgYWNjZXNzX3Rva2VuOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBUd2VldHMge1xuICBjcmVhdGVkX2F0OiBEYXRlO1xuICBpZDogbnVtYmVyO1xuICBpZF9zdHI6IHN0cmluZztcbiAgdGV4dDogc3RyaW5nO1xuICB1c2VyOiBhbnk7XG4gIGVudGl0aWVzOiBhbnk7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3R3ZWV0JyxcbiAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwiY29udGFpbmVyXCIgKm5nSWY9XCJ0d2VldHMgJiYgdHdlZXRzLmxlbmd0aCA+IDBcIj5cbiAgICA8ZGl2PlxuICAgICAgPGg0PmZpbHRlciBieTo8L2g0PlxuICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8bWF0LXNlbGVjdCBbKHZhbHVlKV09XCJmaWx0ZXJCeVwiPlxuICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHQgb2YgZmlsdGVyT3B0aW9uc1wiIHZhbHVlPVwib3B0XCI+e3tvcHR9fTwvbWF0LW9wdGlvbj5cbiAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2Rpdj5cbiAgPG1hdC1jYXJkXG4gICAgKm5nRm9yPVwibGV0IHR0IG9mIHNldEZpbHRlckJ5KClcIlxuICA+XG4gICAgPG1hdC1jYXJkLWhlYWRlcj5cbiAgICAgIDxtYXQtY2FyZC10aXRsZT57e3R0LnVzZXIuc2NyZWVuX25hbWV9fTwvbWF0LWNhcmQtdGl0bGU+XG4gICAgICA8bWF0LWNhcmQtc3VidGl0bGU+QHt7dHQudXNlci5uYW1lfX08L21hdC1jYXJkLXN1YnRpdGxlPlxuICAgIDwvbWF0LWNhcmQtaGVhZGVyPlxuICAgIDxpbWcgbWF0Q2FyZEltYWdlIFtzcmNdPVwidHQudXNlci5wcm9maWxlX2ltYWdlX3VybFwiPlxuICAgIDxtYXQtY2FyZC1jb250ZW50PlxuICAgICAge3t0dC50ZXh0fX1cbiAgICA8L21hdC1jYXJkLWNvbnRlbnQ+XG4gICAgPG1hdC1jYXJkLWFjdGlvbnMgYWxpZ249XCJzdGFydFwiPlxuICAgICAgPCEtLTxidXR0b24gbWF0LWJ1dHRvbiAoY2xpY2spPVwib25BY3Rpb24xXCI+QWN0aW9uMTwvYnV0dG9uPi0tPlxuICAgIDwvbWF0LWNhcmQtYWN0aW9ucz5cbiAgICA8bWF0LWNhcmQtZm9vdGVyPlxuXG4gICAgPC9tYXQtY2FyZC1mb290ZXI+XG4gIDwvbWF0LWNhcmQ+XG4gIDwvZGl2PmAsXG4gIHN0eWxlczogW2BcbiAgICAuY29udGFpbmVyIHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgbWFyZ2luOiAycmVtO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuICBtYXQtY2FyZCB7XG4gICAgbWFyZ2luLWJvdHRvbTogMnJlbTtcbiAgICBmbGV4OiAxIDEgMTAwJTtcbiAgfWBdLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5OYXRpdmVcbn0pXG5leHBvcnQgY2xhc3MgVHdlZXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGtleVB1YmxpYzogc3RyaW5nO1xuICBASW5wdXQoKSBrZXlQcml2YXRlOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGhhc2hUYWc6IHN0cmluZztcbiAgQE91dHB1dCgpIGVycm9yTWVzYWdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIHByaXZhdGUgX3Vuc3Vic2NyaWJlQWxsOiBTdWJqZWN0PGFueT47XG4gIHR3ZWV0czogVHdlZXRzW107XG4gIGZpbHRlckJ5ID0gJ2NyZWF0ZWRfYXQnO1xuICBmaWx0ZXJPcHRpb25zID0gWydjcmVhdGVkX2F0JywgJ3RleHQnLCAndXNlci5uYW1lJ107XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50KSB7XG4gICAgdGhpcy5fdW5zdWJzY3JpYmVBbGwgPSBuZXcgU3ViamVjdCgpO1xuICB9XG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmV2YWxEYXRhKCkpIHtcbiAgICAgIHRoaXMuZ2V0VG9rZW4oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZW5kRXJyb3JNZXNhZ2UoJ05vIFB1YmxpYywgUHJpdml0ZSBLZXknKTtcbiAgICAgIHRoaXMubmdPbkRlc3Ryb3koKTtcbiAgICB9XG4gIH1cbiAgc2V0RmlsdGVyQnkoKSB7XG4gICAgcmV0dXJuIHRoaXMudHdlZXRzLnNvcnQoKGEsIGIpID0+IGFbdGhpcy5maWx0ZXJCeV0gPiBiW3RoaXMuZmlsdGVyQnldID8gMSA6IGFbdGhpcy5maWx0ZXJCeV0gPT09IGJbdGhpcy5maWx0ZXJCeV0gPyAwIDogLTEpO1xuICB9XG4gIHByaXZhdGUgZXZhbERhdGEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMua2V5UHVibGljICYmIHRoaXMua2V5UHJpdmF0ZVxuICAgICAgJiYgdGhpcy5rZXlQdWJsaWMgIT09IG51bGwgJiYgdGhpcy5rZXlQcml2YXRlICE9PSBudWxsXG4gICAgICAmJiB0aGlzLmtleVB1YmxpYyAhPT0gJycgJiYgdGhpcy5rZXlQcml2YXRlICE9PSAnJ1xuICAgICk7XG4gIH1cbiAgcHJpdmF0ZSBldmFIYXNoKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmhhc2hUYWdcbiAgICAgICYmIHRoaXMuaGFzaFRhZyAhPT0gbnVsbFxuICAgICAgJiYgdGhpcy5oYXNoVGFnICE9PSAnJ1xuICAgICk7XG4gIH1cbiAgcHJpdmF0ZSBldmFsVG9rZW4gKHRva2VuOiBUb2tlbikge1xuICAgIHJldHVybiAoXG4gICAgICB0b2tlbi50b2tlbl90eXBlICYmIHRva2VuLmFjY2Vzc190b2tlblxuICAgICAgJiYgdG9rZW4udG9rZW5fdHlwZSAhPT0gbnVsbCAmJiB0b2tlbi5hY2Nlc3NfdG9rZW4gIT09IG51bGxcbiAgICAgICYmIHRva2VuLnRva2VuX3R5cGUgIT09ICcnICYmIHRva2VuLmFjY2Vzc190b2tlbiAhPT0gJydcbiAgICApO1xuICB9XG4gIHByaXZhdGUgZ2V0VG9rZW4oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZXZhSGFzaCgpKSB7XG4gICAgICBjb25zdCBiYXNpYyA9IGJ0b2EoYCR7dGhpcy5rZXlQdWJsaWN9OiR7dGhpcy5rZXlQcml2YXRlfWApO1xuICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycyh7XG4gICAgICAgICdDb250ZW50LVR5cGUnICA6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgICAnQXV0aG9yaXphdGlvbicgICA6IGBCYXNpYyAgJHtiYXNpY31gXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgIHBheWxvYWQuYXBwZW5kKCdncmFudF90eXBlJywgJ2NsaWVudF9jcmVkZW50aWFscycpO1xuICAgICAgdGhpcy5odHRwLnBvc3Q8VG9rZW4+KFR3ZWV0Q29uZmlnLnRva2VuVXJsLCBwYXlsb2FkLCB7IGhlYWRlcnM6IGhlYWRlcnN9KVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fdW5zdWJzY3JpYmVBbGwpKVxuICAgICAgICAuc3Vic2NyaWJlKFxuICAgICAgICAgIHRva2VuID0+IHRoaXMuZ2V0VHdlZXRMaXN0KHRva2VuKSxcbiAgICAgICAgICBlcnJvciA9PiB0aGlzLnNlbmRFcnJvck1lc2FnZShlcnJvcilcbiAgICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZW5kRXJyb3JNZXNhZ2UoJ05vIEhhc2dUYWcgc2V0IEZvciBTZWFyY2hpbmcnKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBnZXRUd2VldExpc3QodG9rZW46IFRva2VuKSB7XG4gICAgaWYgKHRoaXMuZXZhbFRva2VuKHRva2VuKSkge1xuICAgICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycyh7XG4gICAgICAgICdBdXRob3JpemF0aW9uJyAgIDogYCR7dG9rZW4udG9rZW5fdHlwZX0gJHt0b2tlbi5hY2Nlc3NfdG9rZW59YFxuICAgICAgfSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpLnNldCgncScsIGAlMjMke3RoaXMuaGFzaFRhZ31gKTtcbiAgICAgIHRoaXMuaHR0cC5nZXQ8YW55PihUd2VldENvbmZpZy50d2VldFNlYXJjaFVybCwge2hlYWRlcnM6IGhlYWRlcnMsIHBhcmFtczogcGFyYW1zfSlcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX3Vuc3Vic2NyaWJlQWxsKSlcbiAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAoe3N0YXR1c2VzfSkgPT4gdGhpcy50d2VldHMgPSA8VHdlZXRzW10+c3RhdHVzZXMsXG4gICAgICAgICAgZXJyb3IgPT4gdGhpcy5zZW5kRXJyb3JNZXNhZ2UoZXJyb3IpXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VuZEVycm9yTWVzYWdlKCdFcnJvciBUd2VldGVyIFRva2VuJyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgc2VuZEVycm9yTWVzYWdlKG1lbjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5lcnJvck1lc2FnZS5lbWl0KG1lbik7XG4gIH1cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fdW5zdWJzY3JpYmVBbGwubmV4dCgpO1xuICAgIHRoaXMuX3Vuc3Vic2NyaWJlQWxsLmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBUd2VldENvbXBvbmVudCB9IGZyb20gJy4vdHdlZXQuY29tcG9uZW50JztcbmltcG9ydCB7QnJvd3Nlck1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQge0h0dHBDbGllbnRNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7QnJvd3NlckFuaW1hdGlvbnNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQge0Zvcm1zTW9kdWxlfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge01hdENhcmRNb2R1bGUsIE1hdFNlbGVjdE1vZHVsZX0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtUd2VldENvbXBvbmVudF0sXG4gIGltcG9ydHM6IFtcbiAgICBCcm93c2VyTW9kdWxlLFxuICAgIEh0dHBDbGllbnRNb2R1bGUsXG4gICAgQnJvd3NlckFuaW1hdGlvbnNNb2R1bGUsXG4gICAgTWF0Q2FyZE1vZHVsZSxcbiAgICBNYXRTZWxlY3RNb2R1bGUsXG4gICAgRm9ybXNNb2R1bGVcbiAgXSxcbiAgZXhwb3J0czogW1R3ZWV0Q29tcG9uZW50XVxufSlcbmV4cG9ydCBjbGFzcyBUd2VldE1vZHVsZSB7IH1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUEsTUFLYSxZQUFZO0lBRXZCLGlCQUFpQjs7O1lBTGxCLFVBQVUsU0FBQztnQkFDVixVQUFVLEVBQUUsTUFBTTthQUNuQjs7Ozs7Ozs7OztBQ0pEO01BS00sV0FBVyxHQUFHO0lBQ2xCLFFBQVEsRUFBRSxzQ0FBc0M7SUFDaEQsY0FBYyxFQUFFLGdEQUFnRDtDQUNqRTtNQTJEWSxjQUFjOzs7O0lBVXpCLFlBQW9CLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7UUFOMUIsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBR25ELGFBQVEsR0FBRyxZQUFZLENBQUM7UUFDeEIsa0JBQWEsR0FBRyxDQUFDLFlBQVksRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFHbEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0tBQ3RDOzs7O0lBQ0QsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ25CLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUNqQjthQUFNO1lBQ0wsSUFBSSxDQUFDLGVBQWUsQ0FBQyx3QkFB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