<commit_before>namespace Manifold {

    export class ExternalResource implements Manifesto.IExternalResource {

        public authAPIVersion: number;
        public authHoldingPage: any = null;
        public clickThroughService: Manifesto.IService | null = null;
        public data: any;
        public dataUri: string | null;
        public error: any;
        public externalService: Manifesto.IService | null = null;
        public height: number;
        public index: number;
        public isResponseHandled: boolean = false;
        public kioskService: Manifesto.IService | null = null;
        public loginService: Manifesto.IService | null = null;
        public logoutService: Manifesto.IService | null = null;
        public restrictedService: Manifesto.IService | null = null;
        public status: number;
        public tokenService: Manifesto.IService | null = null;
        public width: number;

        constructor(canvas: Manifesto.ICanvas, options: Manifesto.IExternalResourceOptions) {
            canvas.externalResource = <Manifesto.IExternalResource>this;
            this.dataUri = this._getDataUri(canvas);
            this.index = canvas.index;
            this.authAPIVersion = options.authApiVersion;
            this._parseAuthServices(canvas);
            // get the height and width of the image resource if available
            this._parseDimensions(canvas);
        }

        private _getDataUri(canvas: Manifesto.ICanvas): string | null {
            
            const content: Manifesto.IAnnotation[] = canvas.getContent();
            const images: Manifesto.IAnnotation[] = canvas.getImages();

            if (content && content.length) {

                const annotation: Manifesto.IAnnotation = content[0];
                const annotationBody: Manifesto.IAnnotationBody[] = annotation.getBody();

                if (annotationBody.length) {
                    return annotationBody[0].id;
                }

                return null;

            } else if (images && images.length) {

                let infoUri: string | null = null;

                const firstImage: Manifesto.IAnnotation = images[0];
                const resource: Manifesto.IResource = firstImage.getResource();
                const services: Manifesto.IService[] = resource.getServices();

                if (services.length) {
                    for (let i = 0; i < services.length; i++) {
                        const service: Manifesto.IService = services[i];
                        let id: string = service.id;
    
                        if (!id.endsWith('/')) {
                            id += '/';
                        }
    
                        if (manifesto.Utils.isImageProfile(service.getProfile())) {
                            infoUri = id + 'info.json';
                        }
                    }

                    return infoUri;
                }

                // no image services. return the image id
                return resource.id;

            } else {

                // Legacy IxIF
                const service: Manifesto.IService | null = canvas.getService(manifesto.ServiceProfile.ixif());

                if (service) { // todo: deprecate
                    return service.getInfoUri();
                }

                // return the canvas id.
                return canvas.id;
            }
        }

        private _parseAuthServices(resource: any): void {

            if (this.authAPIVersion === 0.9) {

                this.clickThroughService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.clickThrough().toString());
                this.loginService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.login().toString());
                this.restrictedService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.restricted().toString());

                if (this.clickThroughService) {
                    this.logoutService = this.clickThroughService.getService(manifesto.ServiceProfile.logout().toString());
                    this.tokenService = this.clickThroughService.getService(manifesto.ServiceProfile.token().toString());
                } else if (this.loginService) {
                    this.logoutService = this.loginService.getService(manifesto.ServiceProfile.logout().toString());
                    this.tokenService = this.loginService.getService(manifesto.ServiceProfile.token().toString());
                } else if (this.restrictedService) {
                    this.logoutService = this.restrictedService.getService(manifesto.ServiceProfile.logout().toString());
                    this.tokenService = this.restrictedService.getService(manifesto.ServiceProfile.token().toString());
                }

            } else { // auth 1

                this.clickThroughService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1Clickthrough().toString());
                this.loginService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1Login().toString());
                this.externalService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1External().toString());
                this.kioskService = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1Kiosk().toString());

                if (this.clickThroughService) {
                    this.logoutService = this.clickThroughService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.clickThroughService.getService(manifesto.ServiceProfile.auth1Token().toString());
                } else if (this.loginService) {
                    this.logoutService = this.loginService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.loginService.getService(manifesto.ServiceProfile.auth1Token().toString());
                } else if (this.externalService) {
                    this.logoutService = this.externalService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.externalService.getService(manifesto.ServiceProfile.auth1Token().toString());
                } else if (this.kioskService) {
                    this.logoutService = this.kioskService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.kioskService.getService(manifesto.ServiceProfile.auth1Token().toString());
                }<commit_msg>derive authAPIVersion from auth services<commit_after>namespace Manifold {

    export class ExternalResource implements Manifesto.IExternalResource {

        public authAPIVersion: number;
        public authHoldingPage: any = null;
        public clickThroughService: Manifesto.IService | null = null;
        public data: any;
        public dataUri: string | null;
        public error: any;
        public externalService: Manifesto.IService | null = null;
        public height: number;
        public index: number;
        public isResponseHandled: boolean = false;
        public kioskService: Manifesto.IService | null = null;
        public loginService: Manifesto.IService | null = null;
        public logoutService: Manifesto.IService | null = null;
        public restrictedService: Manifesto.IService | null = null;
        public status: number;
        public tokenService: Manifesto.IService | null = null;
        public width: number;

        constructor(canvas: Manifesto.ICanvas, options: Manifesto.IExternalResourceOptions) {
            canvas.externalResource = <Manifesto.IExternalResource>this;
            this.dataUri = this._getDataUri(canvas);
            this.index = canvas.index;
            this._parseAuthServices(canvas);
            // get the height and width of the image resource if available
            this._parseDimensions(canvas);
        }

        private _getDataUri(canvas: Manifesto.ICanvas): string | null {
            
            const content: Manifesto.IAnnotation[] = canvas.getContent();
            const images: Manifesto.IAnnotation[] = canvas.getImages();

            if (content && content.length) {

                const annotation: Manifesto.IAnnotation = content[0];
                const annotationBody: Manifesto.IAnnotationBody[] = annotation.getBody();

                if (annotationBody.length) {
                    return annotationBody[0].id;
                }

                return null;

            } else if (images && images.length) {

                let infoUri: string | null = null;

                const firstImage: Manifesto.IAnnotation = images[0];
                const resource: Manifesto.IResource = firstImage.getResource();
                const services: Manifesto.IService[] = resource.getServices();

                if (services.length) {
                    for (let i = 0; i < services.length; i++) {
                        const service: Manifesto.IService = services[i];
                        let id: string = service.id;
    
                        if (!id.endsWith('/')) {
                            id += '/';
                        }
    
                        if (manifesto.Utils.isImageProfile(service.getProfile())) {
                            infoUri = id + 'info.json';
                        }
                    }

                    return infoUri;
                }

                // no image services. return the image id
                return resource.id;

            } else {

                // Legacy IxIF
                const service: Manifesto.IService | null = canvas.getService(manifesto.ServiceProfile.ixif());

                if (service) { // todo: deprecate
                    return service.getInfoUri();
                }

                // return the canvas id.
                return canvas.id;
            }
        }

        private _parseAuthServices(resource: any): void {

            let auth09_clickThroughService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.clickThrough().toString());
            let auth09_loginService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.login().toString());
            let auth09_restrictedService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.restricted().toString());

            let auth1_clickThroughService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1Clickthrough().toString());
            let auth1_loginService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1Login().toString());
            let auth1_externalService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1External().toString());
            let auth1_kioskService: Manifesto.IService | null = manifesto.Utils.getService(resource, manifesto.ServiceProfile.auth1Kiosk().toString());

            if ( auth09_clickThroughService || auth09_loginService || auth09_restrictedService ) {

              this.authAPIVersion = 0.9;

            }
            else if (

                auth1_clickThroughService || auth1_loginService || auth1_externalService || auth1_kioskService

            ){

              this.authAPIVersion = 1;

            }
            else {

              this.authAPIVersion = 0.9;

            }

            if (this.authAPIVersion === 0.9) {

                this.clickThroughService = auth09_clickThroughService;
                this.loginService = auth09_loginService;
                this.restrictedService = auth09_restrictedService;

                if (this.clickThroughService) {
                    this.logoutService = this.clickThroughService.getService(manifesto.ServiceProfile.logout().toString());
                    this.tokenService = this.clickThroughService.getService(manifesto.ServiceProfile.token().toString());
                } else if (this.loginService) {
                    this.logoutService = this.loginService.getService(manifesto.ServiceProfile.logout().toString());
                    this.tokenService = this.loginService.getService(manifesto.ServiceProfile.token().toString());
                } else if (this.restrictedService) {
                    this.logoutService = this.restrictedService.getService(manifesto.ServiceProfile.logout().toString());
                    this.tokenService = this.restrictedService.getService(manifesto.ServiceProfile.token().toString());
                }

            } else { // auth 1

                this.clickThroughService = auth1_clickThroughService;
                this.loginService = auth1_loginService;
                this.externalService = auth1_externalService;
                this.kioskService = auth1_kioskService;

                if (this.clickThroughService) {
                    this.logoutService = this.clickThroughService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.clickThroughService.getService(manifesto.ServiceProfile.auth1Token().toString());
                } else if (this.loginService) {
                    this.logoutService = this.loginService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.loginService.getService(manifesto.ServiceProfile.auth1Token().toString());
                } else if (this.externalService) {
                    this.logoutService = this.externalService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.externalService.getService(manifesto.ServiceProfile.auth1Token().toString());
                } else if (this.kioskService) {
                    this.logoutService = this.kioskService.getService(manifesto.ServiceProfile.auth1Logout().toString());
                    this.tokenService = this.kioskService.getService(manifesto.ServiceProfile.auth1Token().toString());
                }
{'fraction_non_alphanumeric': 0.09574392748388924, 'fraction_numerical': 0.00516960555201473, 'mean_word_length': 2.058033780857514, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4085472', 'n_tokens_mistral': 3604, 'n_tokens_neox': 3318, 'n_words': 624}