onView() {
    this.data = [];
    const params = {
   'DCode' : this.login_user.districtCode,
   'TCode' : this.login_user.talukId,
   'HostelId' : this.login_user.hostelId,
    }
    this._restApiService.getByParameters(PathConstants.StudentFacilityDetails_Get,params).subscribe(res =>{
      if (res !== null && res !== undefined && res.length !== 0) {
        res.Table.forEach(i => {
          this.data = res.Table;
    })

  } else {
    this._messageService.clear();
    this._messageService.add({
      key: 't-msg', severity: ResponseMessage.SEVERITY_WARNING,
      summary: ResponseMessage.SUMMARY_WARNING, detail: ResponseMessage.NoRecordMessage
    })
  }
});
}


onSelect(type){
    let facilitySelection = [];
    switch (type) {
      case 'FC':
            this.facilityNames.forEach(c => {
              facilitySelection.push({ label:c.FacilityName, value: c.Id });
          })
          this.FacilitynameOptions = facilitySelection;
          this.FacilitynameOptions.unshift({ label: '-select', value: null });
      break;
    }
  }


onDataChecking() {
    this.data = [];
    this.noofCounts = 0;
    this.remarks ='';
    this.FacilityDetailIds =0;
    const params = {
   'DCode' : this.login_user.districtCode,
   'TCode' : this.login_user.talukId,
   'HostelId' : this.login_user.hostelId,
   'FacilityId' : this.facilityName
    }
    this._restApiService.getByParameters(PathConstants.StudentFacilityDetails_Get,params).subscribe(res =>{
      if (res !== null && res !== undefined && res.length !== 0) {
        res.Table.forEach(i => {
        this.noofCounts = i.NoOfCounts;
        this.remarks =i.Remarks;
        this.FacilityDetailIds =i.FacilityDetailId;

    this._messageService.clear();
          this._messageService.add({
            key: 't-msg', severity: ResponseMessage.SEVERITY_INFO,
            summary: ResponseMessage.SUMMARY_ALERT, life: 4000,
            detail: 'Facility already exist'
          })
        })

  } else {
    this._messageService.clear();
    this._messageService.add({
      key: 't-msg', severity: ResponseMessage.SEVERITY_WARNING,
      summary: ResponseMessage.SUMMARY_WARNING, detail: ResponseMessage.NoRecordMessage
    })
  }
});
}


onRowSelect(event, selectedRow) {
   this.FacilityDetailIds = selectedRow.FacilityDetailId;
   this.facilityName = selectedRow.FacilityId;
   this.FacilitynameOptions = [{ label: selectedRow.FacilityName, value: selectedRow.FacilityId}];
   this.noofCounts = selectedRow.NoOfCounts;
   this.remarks = selectedRow.Remarks;
  }


onClear(){
    this.facilityForm.form.markAsUntouched();
    this.facilityName = null;
    this.FacilitynameOptions = [];
    this.noofCounts = null;
    this.remarks = null;
    this.FacilityDetailIds = 0;
  }


(region: string, options?: any) => {
  let regionInfo: RegionInfo | undefined = undefined;
  switch (region) {
    // First, try to match exact region names.
    case "ap-east-1":
      regionInfo = {
        hostname: "iot.ap-east-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "ap-northeast-1":
      regionInfo = {
        hostname: "iot.ap-northeast-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "ap-northeast-2":
      regionInfo = {
        hostname: "iot.ap-northeast-2.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "ap-south-1":
      regionInfo = {
        hostname: "iot.ap-south-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "ap-southeast-1":
      regionInfo = {
        hostname: "iot.ap-southeast-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "ap-southeast-2":
      regionInfo = {
        hostname: "iot.ap-southeast-2.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "ca-central-1":
      regionInfo = {
        hostname: "iot.ca-central-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "cn-north-1":
      regionInfo = {
        hostname: "iot.cn-north-1.amazonaws.com.cn",
        signingService: "execute-api",
      };
      break;
    case "cn-northwest-1":
      regionInfo = {
        hostname: "iot.cn-northwest-1.amazonaws.com.cn",
        signingService: "execute-api",
      };
      break;
    case "eu-central-1":
      regionInfo = {
        hostname: "iot.eu-central-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "eu-north-1":
      regionInfo = {
        hostname: "iot.eu-north-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "eu-west-1":
      regionInfo = {
        hostname: "iot.eu-west-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "eu-west-2":
      regionInfo = {
        hostname: "iot.eu-west-2.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "eu-west-3":
      regionInfo = {
        hostname: "iot.eu-west-3.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "me-south-1":
      regionInfo = {
        hostname: "iot.me-south-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "sa-east-1":
      regionInfo = {
        hostname: "iot.sa-east-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "us-east-1":
      regionInfo = {
        hostname: "iot.us-east-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "us-east-2":
      regionInfo = {
        hostname: "iot.us-east-2.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "us-gov-west-1":
      regionInfo = {
        hostname: "iot.us-gov-west-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "us-west-1":
      regionInfo = {
        hostname: "iot.us-west-1.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    case "us-west-2":
      regionInfo = {
        hostname: "iot.us-west-2.amazonaws.com",
        signingService: "execute-api",
      };
      break;
    // Next, try to match partition endpoints.
    default:
      if (AWS_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_TEMPLATE.replace("{region}", region),
          signingService: "execute-api",
        };
      }
      if (AWS_CN_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_CN_TEMPLATE.replace("{region}", region),
          signingService: "execute-api",
        };
      }
      if (AWS_ISO_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_ISO_TEMPLATE.replace("{region}", region),
        };
      }
      if (AWS_ISO_B_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_ISO_B_TEMPLATE.replace("{region}", region),
        };
      }
      if (AWS_US_GOV_REGIONS.has(region)) {
        regionInfo = {
          hostname: AWS_US_GOV_TEMPLATE.replace("{region}", region),
          signingService: "execute-api",
        };
      }
      // Finally, assume it's an AWS partition endpoint.
      if (regionInfo === undefined) {
        regionInfo = {
          hostname: AWS_TEMPLATE.replace("{region}", region),
          signingService: "execute-api",
        };
      }
  }
  return Promise.resolve(regionInfo);
}


@Component({
  selector: 'firstcancel',
  //styleUrls: ['./application.component.scss'],
  template: `

      <nb-card status="success">
        <nb-card-header>

PAYMENT CANCELLED

        </nb-card-header>
        <nb-card-body>

Please Try again, Your Course is added in Cart.
 Click here, To Go in Cart

          Click here
           To Go Back
        </nb-card-body>
      </nb-card>

`,
})
export class FirstCancelComponent  {

  constructor(private router: Router) {

  }
  async ngOnInit() {

  }

  redirect(){
    this.router.navigateByUrl('/pages/dashboard');
  }

}


async ngOnInit() {

  }


redirect(){
    this.router.navigateByUrl('/pages/dashboard');
  }


@library({ name: 'AsanyEditor', namespace: 'cn.asany.ui.editor.properties' })
class EditorLibrary {
  @component({})
  Input = Input;

  @component({})
  Checkbox = Checkbox;

  @component({})
  CheckboxGroup = Checkbox.Group;

  @component({})
  RadioGroup = Radio.Group;

  @component({})
  InputNumber = InputNumber;

  @component({})
  Select = Select;

  @component({})
  Switch = Switch;

  @component({})
  TextArea = TextArea;

  @component({})
  MultipleWrapper = MultipleWrapper;

  @component({})
  PopoverWrapper = WrapperPopover;

  @component({})
  DefaultMultipleWrapperItem = WrapperItem;
}


function set(value: any) {
        parentData[parentDataProperty] = value;
        return true;
      }


export function resolvePath(obj: any, dataPath: string) {
  const path = dataPath.split("/");
  let ref = obj;
  for (let i = 1; i < path.length; i++) ref = ref[path[i]];
  return ref;
}


function validate({
  source,
  type,
  object,
  schemaKey,
  options,
}: ValidateParams): void {
  const validator = ajv.getSchema(schemaKey);
  if (!validator) throw new Error("No such schema with key: " + schemaKey);

  const valid = validator(object);
  if (valid) return;

  if (type === "result") {
    if (validator.errors)
      validator.errors.forEach((error) => {
        if (error.dataPath !== "")
          // Note, not the regular ajv data value from verbose:true
          error.data = resolvePath(object, error.dataPath);
      });

    if (options.logErrors) {
      const title = encodeURIComponent("Failed validation: " + schemaKey);
      console.log(
        "The following result did not validate with schema: " + schemaKey
      );
      logObj(validator.errors);
      // logObj(object);
      console.log(`
This may happen intermittently and you should catch errors appropriately.
However:  1) if this recently started happening on every request for a symbol
that used to work, Yahoo may have changed their API.  2) If this happens on
every request for a symbol you've never used before, but not for other
symbols, you've found an edge-case.  Please see if anyone has reported
this previously:

  ${pkg.repository}/issues?q=is%3Aissue+${title}

or open a new issue (and mention the symbol):

  ${pkg.repository}/issues/new?title=${title}

For information on how to turn off the above logging or skip these errors,
see https://github.com/gadicc/node-yahoo-finance2/tree/devel/docs/validation.md.
`);
    } /* if (logErrors) */

    throw new FailedYahooValidationError("Failed Yahoo Schema validation", {
      result: object,
      errors: validator.errors,
    });
  } /* if (type === 'options') */ else {
    if (options.logOptionsErrors) {
      console.error(
        `[yahooFinance.${source}] Invalid options ("${schemaKey}")`
      );
      logObj({ errors: validator.errors, input: object });
    }
    throw new InvalidOptionsError(
      `yahooFinance.${source} called with invalid options.`
    );
  }
}


(data, dataCtx) => {
      const { parentData, parentDataProperty } = dataCtx;

      function set(value: any) {
        parentData[parentDataProperty] = value;
        return true;
      }

      if (schema === "number" || schema === "number|null") {
        if (typeof data === "number") return true;

        if (typeof data === "string") {
          let float = Number.parseFloat(data);
          if (Number.isNaN(float)) {
            validate.errors = validate.errors || [];
            validate.errors.push({
              keyword: "yahooFinanceType",
              message: "Number.parseFloat returned NaN",
              params: { schema, data },
            });
            return false;
          }
          return set(float);
        }

        if (data === null) {
          if (schema === "number|null") {
            return true;
          } else {
            validate.errors = validate.errors || [];
            validate.errors.push({
              keyword: "yahooFinanceType",
              message: "Expecting number'ish but got null",
              params: { schema, data },
            });
            return false;
          }
        }

        if (typeof data === "object") {
          if (Object.keys(data).length === 0) {
            // Value of {} becomes null
            // Note, TypeScript types should be "number | null"
            if (schema === "number|null") {
              return set(null);
            } else {
              validate.errors = validate.errors || [];
              validate.errors.push({
                keyword: "yahooFinanceType",
                message:
                  "Got {}->null for 'number', did you want 'number | null' ?",
                params: { schema, data },
              });
              return false;
            }
          }
          if (typeof data.raw === "number") return set(data.raw);
        }
      } else if (schema === "date") {
        if (data instanceof Date) {
          // Validate existing date objects.
          // Generally we receive JSON but in the case of "historical", the
          // csv parser does the date conversion, and we want to validate
          // afterwards.
          return true;
        }

        if (typeof data === "number") return set(new Date(data * 1000));

        if (data === null) return set(null);

        if (typeof data === "object" && typeof data.raw === "number")
          return set(new Date(data.raw * 1000));

        if (typeof data === "string") {
          if (
            data.match(/^\d{4,4}-\d{2,2}-\d{2,2}$/) ||
            data.match(
              /^\d{4,4}-\d{2,2}-\d{2,2}T\d{2,2}:\d{2,2}:\d{2,2}\.\d{3,3}Z$/
            )
          )
            return set(new Date(data));
        }
      } else if (schema === "DateInMs") {
        return set(new Date(data));
      } else if (schema === "TwoNumberRange") {
        if (
          typeof data === "object" &&
          typeof data.low === "number" &&
          typeof data.high === "number"
        )
          return true;
        if (typeof data === "string") {
          const parts = data.split("-").map(parseFloat);
          if (Number.isNaN(parts[0]) || Number.isNaN(parts[1])) {
            validate.errors = validate.errors || [];
            validate.errors.push({
              keyword: "yahooFinanceType",
              message:
                "Number.parseFloat returned NaN: [" + parts.join(",") + "]",
              params: { schema, data },
            });
            return false;
          }
          return set({ low: parts[0], high: parts[1] });
        }
      } else {
        throw new Error("No such yahooFinanceType: " + schema);
      }

      validate.errors = validate.errors || [];
      validate.errors.push({
        keyword: "yahooFinanceType",
        message: "No matching type",
        params: { schema, data },
      });
      return false;
    }


(obj: any) => console.dir(obj, { depth: 4, colors: true })


(obj: any) => console.log(JSON.stringify(obj, null, 2))


(error) => {
        if (error.dataPath !== "")
          // Note, not the regular ajv data value from verbose:true
          error.data = resolvePath(object, error.dataPath);
      }


interface ValidationOptions {
  logErrors: boolean;
  logOptionsErrors: boolean;
}


export interface ValidateParams {
  source: string;
  type: "options" | "result";
  object: object;
  schemaKey: string;
  options: ValidationOptions;
}


compile(schema /*, parentSchema, it */) {
    const validate: SchemaValidateFunction = (data, dataCtx) => {
      const { parentData, parentDataProperty } = dataCtx;

      function set(value: any) {
        parentData[parentDataProperty] = value;
        return true;
      }

      if (schema === "number" || schema === "number|null") {
        if (typeof data === "number") return true;

        if (typeof data === "string") {
          let float = Number.parseFloat(data);
          if (Number.isNaN(float)) {
            validate.errors = validate.errors || [];
            validate.errors.push({
              keyword: "yahooFinanceType",
              message: "Number.parseFloat returned NaN",
              params: { schema, data },
            });
            return false;
          }
          return set(float);
        }

        if (data === null) {
          if (schema === "number|null") {
            return true;
          } else {
            validate.errors = validate.errors || [];
            validate.errors.push({
              keyword: "yahooFinanceType",
              message: "Expecting number'ish but got null",
              params: { schema, data },
            });
            return false;
          }
        }

        if (typeof data === "object") {
          if (Object.keys(data).length === 0) {
            // Value of {} becomes null
            // Note, TypeScript types should be "number | null"
            if (schema === "number|null") {
              return set(null);
            } else {
              validate.errors = validate.errors || [];
              validate.errors.push({
                keyword: "yahooFinanceType",
                message:
                  "Got {}->null for 'number', did you want 'number | null' ?",
                params: { schema, data },
              });
              return false;
            }
          }
          if (typeof data.raw === "number") return set(data.raw);
        }
      } else if (schema === "date") {
        if (data instanceof Date) {
          // Validate existing date objects.
          // Generally we receive JSON but in the case of "historical", the
          // csv parser does the date conversion, and we want to validate
          // afterwards.
          return true;
        }

        if (typeof data === "number") return set(new Date(data * 1000));

        if (data === null) return set(null);

        if (typeof data === "object" && typeof data.raw === "number")
          return set(new Date(data.raw * 1000));

        if (typeof data === "string") {
          if (
            data.match(/^\d{4,4}-\d{2,2}-\d{2,2}$/) ||
            data.match(
              /^\d{4,4}-\d{2,2}-\d{2,2}T\d{2,2}:\d{2,2}:\d{2,2}\.\d{3,3}Z$/
            )
          )
            return set(new Date(data));
        }
      } else if (schema === "DateInMs") {
        return set(new Date(data));
      } else if (schema === "TwoNumberRange") {
        if (
          typeof data === "object" &&
          typeof data.low === "number" &&
          typeof data.high === "number"
        )
          return true;
        if (typeof data === "string") {
          const parts = data.split("-").map(parseFloat);
          if (Number.isNaN(parts[0]) || Number.isNaN(parts[1])) {
            validate.errors = validate.errors || [];
            validate.errors.push({
              keyword: "yahooFinanceType",
              message:
                "Number.parseFloat returned NaN: [" + parts.join(",") + "]",
              params: { schema, data },
            });
            return false;
          }
          return set({ low: parts[0], high: parts[1] });
        }
      } else {
        throw new Error("No such yahooFinanceType: " + schema);
      }

      validate.errors = validate.errors || [];
      validate.errors.push({
        keyword: "yahooFinanceType",
        message: "No matching type",
        params: { schema, data },
      });
      return false;
    };

    return validate;
  }


export type Methods = {
  get: {
    query?: Query
    status: 200
    resBody?: { id: number }
  }

  post: {
    query: Query
    reqBody: Body
    status: 201
    resBody: {
      id: number
      port: string
    }
  }
}


(e: MouseEvent) => (this.open = false)


e => this.onDotClick(e)


prop => this.getMenuOption(prop, this.options[prop])


e => {
          e.preventDefault();
          e.stopPropagation();
          click(e);
          this.open = false;
        }


/**
 * Custom Component used to handle an arrow rendering for TaskGroups utilized in the task component.
 *
 * @export MgtDotOptions
 * @class MgtDotOptions
 * @extends {MgtBaseComponent}
 */
@customElement('mgt-dot-options')
export class MgtDotOptions extends MgtBaseComponent {
  /**
   * Array of styles to apply to the element. The styles should be defined
   * user the `css` tag function.
   */
  public static get styles() {
    return styles;
  }
  /**
   * Determines if header menu is rendered or hidden.
   *
   * @type {boolean}
   * @memberof MgtDotOptions
   */
  @property({ type: Boolean }) public open: boolean;

  /**
   * Menu options to be rendered with an attached MouseEvent handler for expansion of details
   *
   * @memberof MgtDotOptions
   */
  @property({ type: Object }) public options: { [option: string]: (e: MouseEvent) => void | any };

  private _clickHandler: (e: MouseEvent) => void | any = null;

  constructor() {
    super();
    this._clickHandler = (e: MouseEvent) => (this.open = false);
  }

  // tslint:disable-next-line: completed-docs
  public connectedCallback() {
    super.connectedCallback();
    window.addEventListener('click', this._clickHandler);
  }

  // tslint:disable-next-line: completed-docs
  public disconnectedCallback() {
    window.removeEventListener('click', this._clickHandler);
    super.disconnectedCallback();
  }

  /**
   * Invoked on each update to perform rendering tasks. This method must return
   * a lit-html TemplateResult. Setting properties inside this method will *not*
   * trigger the element to update.
   */
  public render() {
    return html`

 this.onDotClick(e)}>
        \uE712

          ${Object.keys(this.options).map(prop => this.getMenuOption(prop, this.options[prop]))}

    `;
  }
  /**
   * Used by the render method to attach click handler to each dot item
   *
   * @param {string} name
   * @param {((e: MouseEvent) => void | any)} click
   * @returns
   * @memberof MgtDotOptions
   */
  public getMenuOption(name: string, click: (e: MouseEvent) => void | any) {
    return html`

 {
          e.preventDefault();
          e.stopPropagation();
          click(e);
          this.open = false;
        }}"
      >

          ${name}

    `;
  }

  private onDotClick(e: MouseEvent) {
    e.preventDefault();
    e.stopPropagation();

    this.open = !this.open;
  }
}


// tslint:disable-next-line: completed-docs
public connectedCallback() {
    super.connectedCallback();
    window.addEventListener('click', this._clickHandler);
  }


// tslint:disable-next-line: completed-docs
public disconnectedCallback() {
    window.removeEventListener('click', this._clickHandler);
    super.disconnectedCallback();
  }


/**
   * Invoked on each update to perform rendering tasks. This method must return
   * a lit-html TemplateResult. Setting properties inside this method will *not*
   * trigger the element to update.
   */
public render() {
    return html`

 this.onDotClick(e)}>
        \uE712

          ${Object.keys(this.options).map(prop => this.getMenuOption(prop, this.options[prop]))}

    `;
  }


/**
   * Used by the render method to attach click handler to each dot item
   *
   * @param {string} name
   * @param {((e: MouseEvent) => void | any)} click
   * @returns
   * @memberof MgtDotOptions
   */
public getMenuOption(name: string, click: (e: MouseEvent) => void | any) {
    return html`
      <div
        class="DotItem"
        @click="${e => {
          e.preventDefault();
          e.stopPropagation();
          click(e);
          this.open = false;
        }}"
      >
        <span class="DotItemName">
          ${name}
        </span>
      </div>
    `;
  }


private onDotClick(e: MouseEvent) {
    e.preventDefault();
    e.stopPropagation();

    this.open = !this.open;
  }


() => {
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [
                AppComponent
            ],
        }).compileComponents();
    }));

    it("should create the app", () => {
        const fixture = TestBed.createComponent(AppComponent);
        const app = fixture.componentInstance;
        expect(app).toBeTruthy();
    });

    // it(`should have as title 'dynamic-form'`, () => {
    //     const fixture = TestBed.createComponent(AppComponent);
    //     const app = fixture.componentInstance;
    //     expect(app.title).toEqual("dynamic-form");
    // });

    // it("should render title", () => {
    //     const fixture = TestBed.createComponent(AppComponent);
    //     fixture.detectChanges();
    //     const compiled = fixture.nativeElement;
    //     expect(compiled.querySelector(".content span").textContent).toContain("dynamic-form app is running!");
    // });
}


() => {
        TestBed.configureTestingModule({
            declarations: [
                AppComponent
            ],
        }).compileComponents();
    }


() => {
        const fixture = TestBed.createComponent(AppComponent);
        const app = fixture.componentInstance;
        expect(app).toBeTruthy();
    }


(theme: Theme) => {
    return {
        icon: {
            fontSize: 18,
            marginRight: 11,
            color: theme.centerChannelColor,
            opacity: 0.56,
        },
        row: {
            paddingHorizontal: 16,
            height: 40,
            flexDirection: 'row',
            alignItems: 'center',
        },
        rowDisplayName: {
            fontSize: 15,
            color: theme.centerChannelColor,
        },
        rowName: {
            fontSize: 15,
            color: theme.centerChannelColor,
            opacity: 0.56,
        },
    };
}


(props: Props) => {
    const insets = useSafeAreaInsets();
    const {
        channelId,
        displayName,
        isBot,
        isGuest,
        name,
        onPress,
        shared,
        testID,
        theme,
        type,
    } = props;

    const completeMention = () => {
        if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) {
            onPress('@' + displayName?.replace(/ /g, ''));
        } else {
            onPress(name);
        }
    };

    const style = getStyleFromTheme(theme);
    const margins = {marginLeft: insets.left, marginRight: insets.right};
    let iconName = 'globe';
    let component;
    if (shared) {
        iconName = type === General.PRIVATE_CHANNEL ? 'circle-multiple-outline-lock' : 'circle-multiple-outline';
    } else if (type === General.PRIVATE_CHANNEL) {
        iconName = 'lock';
    }

    if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) {
        if (!displayName) {
            return null;
        }

        component = (
            <TouchableWithFeedback
                key={channelId}
                onPress={completeMention}
                style={[style.row, margins]}
                testID={testID}
                type={'opacity'}
            >
                <Text style={style.rowDisplayName}>{'@' + displayName}</Text>
                <BotTag
                    show={isBot}
                    theme={theme}
                />
                <GuestTag
                    show={isGuest}
                    theme={theme}
                />
            </TouchableWithFeedback>


() => {
        if (type === General.DM_CHANNEL || type === General.GM_CHANNEL) {
            onPress('@' + displayName?.replace(/ /g, ''));
        } else {
            onPress(name);
        }
    }


type Props = {
    channelId: string;
    displayName?: string;
    name?: string;
    type?: string;
    isBot: boolean;
    isGuest: boolean;
    onPress: (name?: string) => void;
    theme: Theme;
    shared: boolean;
    testID?: string;
};


changeOpacity(theme


export interface FloodProcessEnv {
	BROWSER_ID: number
	FLOOD_GRID_REGION: string
	FLOOD_GRID_SQEUENCE_ID: number
	FLOOD_GRID_SEQUENCE_ID: number
	FLOOD_GRID_INDEX: number
	FLOOD_GRID_NODE_SEQUENCE_ID: number
	FLOOD_NODE_INDEX: number
	FLOOD_SEQUENCE_ID: number
	FLOOD_PROJECT_ID: number

	/**
	 * Globally unique sequence number for this browser instance.
	 */
	SEQUENCE: number

	/**
	 * `true` when running as a load test on https://flood.io
	 * `false` otherwise
	 *
	 * This can be useful for changing settings based on whether you're
	 * testing your script locally or running it as a fully fledged load test.
	 */
	FLOOD_LOAD_TEST: boolean
}


export interface RuntimeEnvironment {
	stepEnv(): FloodProcessEnv
	workRoot: WorkRoot
}


export interface WorkRoot {
	ensureCreated(): void

	join(kind: WorkRootKind, ...segments: string[]): string

	testData(filename: string): string
}


export type SpecialSubRoot = 'test-data'


export type SubRoot = 'objects' | 'screenshots' | 'files' | 'results' | 'network' | 'traces'


export type WorkRootKind = SubRoot | SpecialSubRoot


export function isSocket(value: Transport | undefined): value is SocketTransport {
		const candidate = value as SocketTransport;
		return candidate && candidate.kind === TransportKind.socket && Is.number(candidate.port);
	}


export function is(value: any): value is Executable {
		return Is.string(value.command);
	}


export function is(value: any): value is NodeModule {
		return Is.string(value.module);
	}


export function is(value: any): value is StreamInfo {
		let candidate = value as StreamInfo;
		return candidate && candidate.writer !== undefined && candidate.reader !== undefined;
	}


export function is(value: any): value is ChildProcessInfo {
		let candidate = value as ChildProcessInfo;
		return candidate && candidate.process !== undefined && typeof candidate.detached === 'boolean';
	}


function getEnvironment(env: any, fork: boolean): any {
			if (!env && !fork) {
				return undefined;
			}
			const result: any = Object.create(null);
			Object.keys(process.env).forEach(key => result[key] = process.env[key]);
			if (fork) {
				result['ELECTRON_RUN_AS_NODE'] = '1';
				result['ELECTRON_NO_ASAR'] = '1';
			}
			if (env) {
				Object.keys(env).forEach(key => result[key] = env[key]);
			}
			return result;
		}


function startedInDebugMode(): boolean {
			let args: string[] = (process as any).execArgv;
			if (args) {
				return args.some((arg) => {
					return debugStartWith.some(value => arg.startsWith(value)) ||
						debugEquals.some(value => arg === value);
				});
			}
			return false;
		}


function assertStdio(process: cp.ChildProcess): asserts process is cp.ChildProcessWithoutNullStreams {
			if (process.stdin === null || process.stdout === null || process.stderr === null) {
				throw new Error('Process created without stdio streams');
			}
		}


function handleChildProcessStartError(process: ChildProcess, message: string) {
	if (process == null) {
		return Promise.reject<MessageTransports>(message);
	}

	return new Promise<MessageTransports>((_, reject) => {
		process.on('error', (err) => {
			reject(`${message} ${err}`);
		});
		// the error event should always be run immediately,
		// but race on it just in case
		setImmediate(() => reject(message));
	});
}


(resolve) => setTimeout(resolve, 1000)


() => {
			if (this._serverProcess) {
				const toCheck = this._serverProcess;
				this._serverProcess = undefined;
				if (this._isDetached === undefined || !this._isDetached) {
					this.checkProcessDied(toCheck);
				}
				this._isDetached = undefined;
			}
		}


() => {
			// Test if the process is still alive. Throws an exception if not
			try {
				process.kill(childProcess.pid, <any>0);
				terminate(childProcess);
			} catch (error) {
				// All is fine.
			}
		}


key => result[key] = process.env[key]


key => result[key] = env[key]


(arg) => {
					return debugStartWith.some(value => arg.startsWith(value)) ||
						debugEquals.some(value => arg === value);
				}


value => arg.startsWith(value)


value => arg === value


(result) => {
				if (MessageTransports.is(result)) {
					this._isDetached = !!result.detached;
					return result;
				} else if (StreamInfo.is(result)) {
					this._isDetached = !!result.detached;
					return { reader: new StreamMessageReader(result.reader), writer: new StreamMessageWriter(result.writer) };
				} else {
					let cp: ChildProcess;
					if (ChildProcessInfo.is(result)) {
						cp = result.process;
						this._isDetached = result.detached;
					} else {
						cp = result;
						this._isDetached = false;
					}
					cp.stderr!.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
					return { reader: new StreamMessageReader(cp.stdout!), writer: new StreamMessageWriter(cp.stdin!) };
				}
			}


data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding))


element => args.push(element)


(transport) => {
							const process = cp.spawn(runtime, args, execOptions);
							if (!process || !process.pid) {
								return handleChildProcessStartError(process, `Launching server using runtime ${runtime} failed.`);
							}
							this._serverProcess = process;
							process.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
							process.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
							return transport.onConnected().then((protocol) => {
								return { reader: protocol[0], writer: protocol[1] };
							});
						}


(protocol) => {
								return { reader: protocol[0], writer: protocol[1] };
							}


(resolve, reject) => {
						const args = (node.args && node.args.slice()) ?? [];
						if (transport === TransportKind.ipc) {
							args.push('--node-ipc');
						} else if (transport === TransportKind.stdio) {
							args.push('--stdio');
						} else if (transport === TransportKind.pipe) {
							pipeName = generateRandomPipeName();
							args.push(`--pipe=${pipeName}`);
						} else if (Transport.isSocket(transport)) {
							args.push(`--socket=${transport.port}`);
						}
						args.push(`--clientProcessId=${process.pid.toString()}`);
						const options: cp.ForkOptions = node.options ?? Object.create(null);
						options.env = getEnvironment(options.env, true);
						options.execArgv = options.execArgv || [];
						options.cwd = serverWorkingDir;
						options.silent = true;
						if (transport === TransportKind.ipc || transport === TransportKind.stdio) {
							const sp = cp.fork(node.module, args || [], options);
							assertStdio(sp);
							this._serverProcess = sp;
							sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
							if (transport === TransportKind.ipc) {
								sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								resolve({ reader: new IPCMessageReader(this._serverProcess), writer: new IPCMessageWriter(this._serverProcess) });
							} else {
								resolve({ reader: new StreamMessageReader(sp.stdout), writer: new StreamMessageWriter(sp.stdin) });
							}
						} else if (transport === TransportKind.pipe) {
							createClientPipeTransport(pipeName!).then((transport) => {
								const sp = cp.fork(node.module, args || [], options);
								assertStdio(sp);
								this._serverProcess = sp;
								sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								transport.onConnected().then((protocol) => {
									resolve({ reader: protocol[0], writer: protocol[1] });
								}, reject);
							}, reject);
						} else if (Transport.isSocket(transport)) {
							createClientSocketTransport(transport.port).then((transport) => {
								const sp = cp.fork(node.module, args || [], options);
								assertStdio(sp);
								this._serverProcess = sp;
								sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								transport.onConnected().then((protocol) => {
									resolve({ reader: protocol[0], writer: protocol[1] });
								}, reject);
							}, reject);
						}
					}


(transport) => {
								const sp = cp.fork(node.module, args || [], options);
								assertStdio(sp);
								this._serverProcess = sp;
								sp.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								sp.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
								transport.onConnected().then((protocol) => {
									resolve({ reader: protocol[0], writer: protocol[1] });
								}, reject);
							}


(protocol) => {
									resolve({ reader: protocol[0], writer: protocol[1] });
								}


(transport) => {
						const serverProcess = cp.spawn(command.command, args, options);
						if (!serverProcess || !serverProcess.pid) {
							return handleChildProcessStartError(serverProcess, `Launching server using command ${command.command} failed.`);
						}
						this._serverProcess = serverProcess;
						this._isDetached = !!options.detached;
						serverProcess.stderr.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
						serverProcess.stdout.on('data', data => this.outputChannel.append(Is.string(data) ? data : data.toString(encoding)));
						return transport.onConnected().then((protocol) => {
							return { reader: protocol[0], writer: protocol[1] };
						});
					}


(protocol) => {
							return { reader: protocol[0], writer: protocol[1] };
						}


s => {
				fs.lstat(cwd!, (err, stats) => {
					s(!err && stats.isDirectory() ? cwd : undefined);
				});
			}


(err, stats) => {
					s(!err && stats.isDirectory() ? cwd : undefined);
				}


() => {
			if (this._client.needsStop()) {
				void this._client.stop();
			}
		}


(_, reject) => {
		process.on('error', (err) => {
			reject(`${message} ${err}`);
		});
		// the error event should always be run immediately,
		// but race on it just in case
		setImmediate(() => reject(message));
	}


(err) => {
			reject(`${message} ${err}`);
		}


() => reject(message)


export class SettingMonitor {

	private _listeners: Disposable[];

	constructor(private _client: LanguageClient, private _setting: string) {
		this._listeners = [];
	}

	public start(): Disposable {
		Workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this._listeners);
		this.onDidChangeConfiguration();
		return new Disposable(() => {
			if (this._client.needsStop()) {
				void this._client.stop();
			}
		});
	}

	private onDidChangeConfiguration(): void {
		let index = this._setting.indexOf('.');
		let primary = index >= 0 ? this._setting.substr(0, index) : this._setting;
		let rest = index >= 0 ? this._setting.substr(index + 1) : undefined;
		let enabled = rest ? Workspace.getConfiguration(primary).get(rest, false) : Workspace.getConfiguration(primary);
		if (enabled && this._client.needsStart()) {
			this._client.start();
		} else if (!enabled && this._client.needsStop()) {
			void this._client.stop();
		}
	}
}


export interface SocketTransport {
	kind: TransportKind.socket;
	port: number;
}


export interface ExecutableOptions {
	cwd?: string;
	env?: any;
	detached?: boolean;
	shell?: boolean;
}


export interface Executable {
	command: string;
	transport?: Transport;
	args?: string[];
	options?: ExecutableOptions;
}


export interface ForkOptions {
	cwd?: string;
	env?: any;
	encoding?: string;
	execArgv?: string[];
}


export interface NodeModule {
	module: string;
	transport?: Transport;
	args?: string[];
	runtime?: string;
	options?: ForkOptions;
}


export interface StreamInfo {
	writer: NodeJS.WritableStream;
	reader: NodeJS.ReadableStream;
	detached?: boolean;
}


export interface ChildProcessInfo {
	process: ChildProcess;
	detached: boolean;
}


interface NLS_CONFIG {
			locale: string;
		}


export enum TransportKind {
	stdio,
	ipc,
	pipe,
	socket
}


/**
 * To avoid any timing, pipe name or port number issues the pipe (TransportKind.pipe)
 * and the sockets (TransportKind.socket and SocketTransport) are owned by the
 * VS Code processes. The server process simply connects to the pipe / socket.
 * In node term the VS Code process calls `createServer`, then starts the server
 * process, waits until the server process has connected to the pipe / socket
 * and then signals that the connection has been established and messages can
 * be send back and forth. If the language server is implemented in a different
 * program language the server simply needs to create a connection to the
 * passed pipe name or port number.
 */
export type Transport = TransportKind | SocketTransport;


export type ServerOptions = Executable | { run: Executable; debug: Executable } | { run: NodeModule; debug: NodeModule } | NodeModule | (() => Promise<ChildProcess | StreamInfo | MessageTransports | ChildProcessInfo>);


private checkVersion() {
		const codeVersion = SemVer.parse(VSCodeVersion);
		if (!codeVersion) {
			throw new Error(`No valid VS Code version detected. Version string is: ${VSCodeVersion}`);
		}
		// Remove the insider pre-release since we stay API compatible.
		if (codeVersion.prerelease && codeVersion.prerelease.length > 0) {
			codeVersion.prerelease = [];
		}
		if (!SemVer.satisfies(codeVersion, REQUIRED_VSCODE_VERSION)) {
			throw new Error(`The language client requires VS Code version ${REQUIRED_VSCODE_VERSION} but received version ${VSCodeVersion}`);
		}
	}


public async restart(): Promise<void> {
		await this.stop();
		// We are in debug mode. Wait a little before we restart
		// so that the debug port can be freed. We can safely ignore
		// the disposable returned from start since it will call
		// stop on the same client instance.
		if (this.isInDebugMode) {
			await new Promise((resolve) => setTimeout(resolve, 1000));
			this.start();
		} else {
			this.start();
		}
	}


public stop(timeout: number = 2000): Promise<void> {
		return super.stop(timeout).finally(() => {
			if (this._serverProcess) {
				const toCheck = this._serverProcess;
				this._serverProcess = undefined;
				if (this._isDetached === undefined || !this._isDetached) {
					this.checkProcessDied(toCheck);
				}
				this._isDetached = undefined;
			}
		});
	}


private checkProcessDied(childProcess: ChildProcess | undefined): void {
		if (!childProcess) {
			return;
		}
		setTimeout(() => {
			// Test if the process is still alive. Throws an exception if not
			try {
				process.kill(childProcess.pid, <any>0);
				terminate(childProcess);
			} catch (error) {
				// All is fine.
			}
		}, 2000);
	}


protected handleConnectionClosed() {
		this._serverProcess = undefined;
		super.handleConnectionClosed();
	}


protected fillInitializeParams(params: InitializeParams): void {
		super.fillInitializeParams(params);
		if (params.processId === null) {
			params.processId = process.pid;
		}
	}


private _getRuntimePath(runtime: string, serverWorkingDirectory: string | undefined): string {
		if (path.isAbsolute(runtime)) {
			return runtime;
		}
		const mainRootPath = this._mainGetRootPath();
		if (mainRootPath !== undefined) {
			const result = path.join(mainRootPath, runtime);
			if (fs.existsSync(result)) {
				return result;
			}
		}
		if (serverWorkingDirectory !== undefined) {
			const result = path.join(serverWorkingDirectory, runtime);
			if (fs.existsSync(result)) {
				return result;
			}
		}
		return runtime;
	}


private _mainGetRootPath(): string | undefined {
		let folders = Workspace.workspaceFolders;
		if (!folders || folders.length === 0) {
			return undefined;
		}
		let folder = folders[0];
		if (folder.uri.scheme === 'file') {
			return folder.uri.fsPath;
		}
		return undefined;
	}


private _getServerWorkingDir(options?: { cwd?: string }): Promise<string | undefined> {
		let cwd = options && options.cwd;
		if (!cwd) {
			cwd = this.clientOptions.workspaceFolder
				? this.clientOptions.workspaceFolder.uri.fsPath
				: this._mainGetRootPath();
		}
		if (cwd) {
			// make sure the folder exists otherwise creating the process will fail
			return new Promise(s => {
				fs.lstat(cwd!, (err, stats) => {
					s(!err && stats.isDirectory() ? cwd : undefined);
				});
			});
		}
		return Promise.resolve(undefined);
	}


public getLocale(): string {
		interface NLS_CONFIG {
			locale: string;
		}
		const envValue = process.env['VSCODE_NLS_CONFIG'];
		if (envValue === undefined) {
			return 'en';
		}

		let config: NLS_CONFIG | undefined = undefined;
		try  {
			config = JSON.parse(envValue);
		} catch (err) {
		}
		if (config === undefined || typeof config.locale !== 'string') {
			return 'en';
		}
		return config.locale;
	}


public start(): Disposable {
		Workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this._listeners);
		this.onDidChangeConfiguration();
		return new Disposable(() => {
			if (this._client.needsStop()) {
				void this._client.stop();
			}
		});
	}


private onDidChangeConfiguration(): void {
		let index = this._setting.indexOf('.');
		let primary = index >= 0 ? this._setting.substr(0, index) : this._setting;
		let rest = index >= 0 ? this._setting.substr(index + 1) : undefined;
		let enabled = rest ? Workspace.getConfiguration(primary).get(rest, false) : Workspace.getConfiguration(primary);
		if (enabled && this._client.needsStart()) {
			this._client.start();
		} else if (!enabled && this._client.needsStop()) {
			void this._client.stop();
		}
	}


@NgModule({
  imports: [
    CommonModule,
    ReportshowsRoutingModule,
    EditorModule,
    NgZorroAntdModule
  ],
  declarations: [
    ReportshowComponent,
    ReportshowotherComponent,
    ReportAuthorInfoComponent
  ],
  providers: [{ provide: NZ_I18N, useValue: en_US }],
})
export class ReportshowsModule { }


scope => {
  return [{
    name: 'name',
    filter(_, file: IFile, index, compile) {
      return compile(`

          insert_drive_file
          {{::file.name}}
          {{::path}}

      `, {file}, scope);
    }
  // }, {
  //   name: 'path',
  //   filter(_, file: IFile, index, compile) {
  //     return compile(`
  //       {{::path}}
  //     `, {path: `/${file.path.slice(1).map(({name}) => name).join('/')}`}, scope);
  //   }
  }, {
    name: 'owner',
  }, {
    name: 'liked',
    title: ' ',
    sort: false,
    filter(_, file: IFile, index, compile) {
      return compile(`

          {{::file.isLiked ? 'favorite' :'favorite_border'}}

      `, {file}, scope);
    }
  }];
}


filter(_, file: IFile, index, compile) {
      return compile(`

          insert_drive_file
          {{::file.name}}
          {{::path}}

      `, {file}, scope);
    }


filter(_, file: IFile, index, compile) {
      return compile(`

          {{::file.isLiked ? 'favorite' :'favorite_border'}}

      `, {file}, scope);
    }


export class MockUserDB implements UserDatabase {
  constructor(private readonly passed?: GitHubUser) {}

  readonly onRegister = new EventEmitter();

  register(id: DiscordId, user: GitHubUser): Promise<void> {
    this.onRegister.emit(placeholder, {
      id,
      user,
    });
    return Promise.resolve();
  }

  readonly onUnregister = new EventEmitter();

  unregister(id: DiscordId): Promise<boolean> {
    this.onUnregister.emit(placeholder, id);
    return Promise.resolve(true);
  }

  fetchUser(): Promise<GitHubUser | null> {
    return Promise.resolve(this.passed ?? null);
  }
}


register(id: DiscordId, user: GitHubUser): Promise<void> {
    this.onRegister.emit(placeholder, {
      id,
      user,
    });
    return Promise.resolve();
  }


unregister(id: DiscordId): Promise<boolean> {
    this.onUnregister.emit(placeholder, id);
    return Promise.resolve(true);
  }


fetchUser(): Promise<GitHubUser | null> {
    return Promise.resolve(this.passed ?? null);
  }


async ({ totalScore, courseId }: StudentStats): Promise<StudentPosition> =>
  (
    await getRepository(Student)
      .createQueryBuilder('student')
      .select('"student"."courseId" AS "courseId"')
      .addSelect('COUNT(*) AS "position"')
      .where('"student"."courseId" = :courseId', { courseId })
      .andWhere('"student"."totalScore" >= :totalScore', { totalScore })
      .groupBy('"student"."courseId"')
      .getRawMany()
  ).map(({ courseId, position }) => ({ courseId, position: Number(position) }))[0]


({ courseId, position }) => ({ courseId, position: Number(position) })


async (githubId: string, permissions: Permissions): Promise<StudentStats[]> => {
  const { isCoreJsFeedbackVisible, isExpellingReasonVisible } = permissions;

  const query = await getRepository(Student)
    .createQueryBuilder('student')
    .select('"course"."id" AS "courseId"')
    .addSelect('"course"."name" AS "courseName"')
    .addSelect('"course"."locationName" AS "locationName"')
    .addSelect('"course"."fullName" AS "courseFullName"')
    .addSelect('"student"."isExpelled" AS "isExpelled"')
    .addSelect('"student"."courseCompleted" AS "isCourseCompleted"')
    .addSelect('"student"."totalScore" AS "totalScore"')
    .addSelect('"userMentor"."firstName" AS "mentorFirstName"')
    .addSelect('"userMentor"."lastName" AS "mentorLastName"')
    .addSelect('"userMentor"."githubId" AS "mentorGithubId"')
    .addSelect('"certificate"."publicId" AS "certificateId"')
    .addSelect('ARRAY_AGG ("courseTask"."maxScore") AS "taskMaxScores"')
    .addSelect('ARRAY_AGG ("courseTask"."scoreWeight") AS "taskScoreWeights"')
    .addSelect('ARRAY_AGG ("task"."name") AS "taskNames"')
    .addSelect('ARRAY_AGG ("task"."descriptionUrl") AS "taskDescriptionUris"')
    .addSelect('ARRAY_AGG ("taskResult"."githubPrUrl") AS "taskGithubPrUris"');

  if (isExpellingReasonVisible) {
    query.addSelect('"student"."expellingReason" AS "expellingReason"');
  }

  if (isCoreJsFeedbackVisible) {
    query
      .addSelect('ARRAY_AGG (COALESCE("taskResult"."score", "taskInterview"."score")) AS "taskScores"')
      .addSelect('ARRAY_AGG (COALESCE("taskResult"."comment", "taskInterview"."comment")) AS "taskComments"')
      .addSelect('ARRAY_AGG ("taskInterview"."formAnswers") AS "taskInterviewFormAnswers"')
      .addSelect('ARRAY_AGG ("interviewer"."githubId") AS "interviewerGithubId"')
      .addSelect('ARRAY_AGG ("interviewer"."firstName") AS "interviewerFirstName"')
      .addSelect('ARRAY_AGG ("interviewer"."lastName") AS "interviewerLastName"');
  } else {
    query
      .addSelect('ARRAY_AGG (COALESCE("taskResult"."score", "taskInterview"."score")) AS "taskScores"')
      .addSelect('ARRAY_AGG ("taskResult"."comment") AS "taskComments"');
  }

  query
    .leftJoin(User, 'user', '"user"."id" = "student"."userId"')
    .leftJoin(Certificate, 'certificate', '"certificate"."studentId" = "student"."id"')
    .leftJoin(Course, 'course', '"course"."id" = "student"."courseId"')
    .leftJoin(Mentor, 'mentor', '"mentor"."id" = "student"."mentorId"')
    .leftJoin(User, 'userMentor', '"userMentor"."id" = "mentor"."userId"')
    .leftJoin(CourseTask, 'courseTask', '"courseTask"."courseId" = "student"."courseId"')
    .leftJoin(Task, 'task', '"courseTask"."taskId" = "task"."id"')
    .leftJoin(
      TaskResult,
      'taskResult',
      '"taskResult"."studentId" = "student"."id" AND "taskResult"."courseTaskId" = "courseTask"."id"',
    )
    .leftJoin(
      TaskInterviewResult,
      'taskInterview',
      '"taskInterview"."studentId" = "student"."id" AND "taskInterview"."courseTaskId" = "courseTask"."id"',
    );

  if (isCoreJsFeedbackVisible) {
    query
      .leftJoin(Mentor, 'mentorInterviewer', '"mentorInterviewer"."id" = "taskInterview"."mentorId"')
      .leftJoin(User, 'interviewer', '"interviewer"."id" = "mentorInterviewer"."userId"');
  }

  query
    .where('"user"."githubId" = :githubId', { githubId })
    .andWhere('courseTask.disabled = :disabled', { disabled: false })
    .groupBy('"course"."id", "student"."id", "userMentor"."id", "certificate"."publicId"')
    .orderBy('"course"."endDate"', 'DESC');

  const rawStats = await query.getRawMany();

  return rawStats.map(
    ({
      courseId,
      courseName,
      locationName,
      courseFullName,
      isExpelled,
      expellingReason,
      isCourseCompleted,
      totalScore,
      mentorFirstName,
      mentorLastName,
      mentorGithubId,
      taskMaxScores,
      taskScoreWeights,
      taskNames,
      taskDescriptionUris,
      taskGithubPrUris,
      taskScores,
      taskComments,
      taskInterviewFormAnswers,
      interviewerGithubId,
      interviewerFirstName,
      interviewerLastName,
      certificateId,
    }: any) => {
      const tasks = taskMaxScores.map((maxScore: number, idx: number) => ({
        maxScore,
        scoreWeight: taskScoreWeights[idx],
        name: taskNames[idx],
        descriptionUri: taskDescriptionUris[idx],
        githubPrUri: taskGithubPrUris[idx],
        score: taskScores[idx],
        comment: taskComments[idx],
        interviewFormAnswers: (taskInterviewFormAnswers && taskInterviewFormAnswers[idx]) || undefined,
        interviewer:
          interviewerGithubId && interviewerGithubId[idx]
            ? {
                name: getFullName(interviewerFirstName[idx], interviewerLastName[idx], interviewerGithubId[idx]),
                githubId: interviewerGithubId[idx],
              }
            : undefined,
      }));
      return {
        courseId,
        courseName,
        locationName,
        courseFullName,
        isExpelled,
        expellingReason,
        isCourseCompleted,
        totalScore,
        tasks,
        certificateId,
        position: null,
        mentor: {
          githubId: mentorGithubId,
          name: getFullName(mentorFirstName, mentorLastName, mentorGithubId),
        },
      };
    },
  );
}


({
      courseId,
      courseName,
      locationName,
      courseFullName,
      isExpelled,
      expellingReason,
      isCourseCompleted,
      totalScore,
      mentorFirstName,
      mentorLastName,
      mentorGithubId,
      taskMaxScores,
      taskScoreWeights,
      taskNames,
      taskDescriptionUris,
      taskGithubPrUris,
      taskScores,
      taskComments,
      taskInterviewFormAnswers,
      interviewerGithubId,
      interviewerFirstName,
      interviewerLastName,
      certificateId,
    }: any) => {
      const tasks = taskMaxScores.map((maxScore: number, idx: number) => ({
        maxScore,
        scoreWeight: taskScoreWeights[idx],
        name: taskNames[idx],
        descriptionUri: taskDescriptionUris[idx],
        githubPrUri: taskGithubPrUris[idx],
        score: taskScores[idx],
        comment: taskComments[idx],
        interviewFormAnswers: (taskInterviewFormAnswers && taskInterviewFormAnswers[idx]) || undefined,
        interviewer:
          interviewerGithubId && interviewerGithubId[idx]
            ? {
                name: getFullName(interviewerFirstName[idx], interviewerLastName[idx], interviewerGithubId[idx]),
                githubId: interviewerGithubId[idx],
              }
            : undefined,
      }));
      return {
        courseId,
        courseName,
        locationName,
        courseFullName,
        isExpelled,
        expellingReason,
        isCourseCompleted,
        totalScore,
        tasks,
        certificateId,
        position: null,
        mentor: {
          githubId: mentorGithubId,
          name: getFullName(mentorFirstName, mentorLastName, mentorGithubId),
        },
      };
    }


(maxScore: number, idx: number) => ({
        maxScore,
        scoreWeight: taskScoreWeights[idx],
        name: taskNames[idx],
        descriptionUri: taskDescriptionUris[idx],
        githubPrUri: taskGithubPrUris[idx],
        score: taskScores[idx],
        comment: taskComments[idx],
        interviewFormAnswers: (taskInterviewFormAnswers && taskInterviewFormAnswers[idx]) || undefined,
        interviewer:
          interviewerGithubId && interviewerGithubId[idx]
            ? {
                name: getFullName(interviewerFirstName[idx], interviewerLastName[idx], interviewerGithubId[idx]),
                githubId: interviewerGithubId[idx],
              }
            : undefined,
      })


async (githubId: string, permissions: Permissions) => {
  const studentStats = await getStudentStatsWithoutPosition(githubId, permissions);
  const studentPositions = await Promise.all(studentStats.map(stats => getStudentPosition(stats)));
  const studentStatsWithPositions = studentStats.map((stats, idx) => ({ ...stats, ...studentPositions[idx] }));

  return studentStatsWithPositions;
}


stats => getStudentPosition(stats)


(stats, idx) => ({ ...stats, ...studentPositions[idx] })


type StudentPosition = {
  courseId: number;
  position: number;
};


(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
  console.log(e, 'I was closed.');
}


() => {
  return (
    <>
      <FcAlert
        message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
        type="warning"
        closable
        onClose={onClose}
      />
      <FcAlert
        message="Error Text"
        description="Error Description Error Description Error Description Error Description Error Description Error Description"
        type="error"
        closable
        onClose={onClose}
      />
    </>
  );
}


function* requestUsersSaga() {
  try {
    const { data } = yield call(() => api.get('/users'));
    yield put(actions.requestUsersSuccess(data));
  } catch (e) {
    yield put(actions.requestUsersFailure(e));
  }
}


function* requestUserSaga({
  payload: { userId },
}: ReturnType<typeof actions.requestUser>) {
  try {
    const { data } = yield call(() => api.get(`/users/${userId}`));
    yield put(actions.requestUserSuccess(data));
  } catch (e) {
    yield put(actions.requestUserFailure(e));
  }
}


export default function* usersSaga() {
  yield all([
    takeLatest(actions.requestUser, requestUserSaga),
    takeLatest(actions.requestUsers, requestUsersSaga),
  ]);
}


() => api.get('/users')


() => api.get(`/users/${userId}`)


() => {
  let component: NoStudentErrorComponent;
  let fixture: ComponentFixture<NoStudentErrorComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ NoStudentErrorComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(NoStudentErrorComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
}


async () => {
    await TestBed.configureTestingModule({
      declarations: [ NoStudentErrorComponent ]
    })
    .compileComponents();
  }


() => {
    fixture = TestBed.createComponent(NoStudentErrorComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }


(props: Props): React.CSSProperties => ({
  '--surface-elevation-shadow': `var(--elevation-shadow-${props.elevation})`,
  '--surface-elevation-overlay-opacity': `var(--elevation-overlay-opacity-${props.elevation})`,
  '--surface-border-radius': `${props.radius}px`,
  '--surface-height': props.height,
})


(props: React.PropsWithChildren<Props>) => (
  <div className={Styles.container}


export interface CSSProperties {
    '--surface-elevation-shadow'?: string,
    '--surface-elevation-overlay-opacity'?: string,
    '--surface-border-radius'?: string,
    '--surface-height'?: string,
  }


type Elevation =
  | '0dp'
  | '1dp'
  | '2dp'
  | '3dp'
  | '4dp'
  | '6dp'
  | '8dp'
  | '12dp'
  | '16dp'
  | '24dp'


type Props = {
  elevation: Elevation,
  radius: number,
  height: string
}


buildStyle(props)


async ({mode}) => {
    if (mode !== 'production') {
        return null;
    }

    try {
        const {default: loaderFactory} = await import('@reskript/config-img-loader');
        return loaderFactory();
    }
    catch {
        return null;
    }
}


() => {
    this.props.dispatch(getChannelMembers(this.props.chatId));
  }


({item: memberId, index}) => {
    const isFirst = index === 0;
    const isLast = index === this.props.membersList.length - 1;
    return <ChannelMemberCell memberId={memberId} isFirst={isFirst} isLast={isLast} />;
  }


() => {
    let {chatId, chat, theme} = this.props;
    return (
      <>
        <InfoBox isList={false} style={{flexDirection: 'row'}}


(state: RootState, ownProps) => {
  let chatId = ownProps.chatId ?? ownProps?.navigation.getParam('chatId');
  let chat = state.entities.chats.byId[chatId];
  let chatType = getChatType(chat);
  let user = chat && chatType === 'direct' && state.entities.users.byId[chat.user_id];
  return {
    chatId,
    chat,
    chatType,
    user,

    membersList: state.chats.membersList[chatId],
    membersListLoading: state.chats.membersListLoadStatus[chatId]?.loading ?? false,
  };
}


class ChatDetails extends Component<Props> {
  componentDidMount() {
    this.getChannelMembers();
  }

  componentDidUpdate(prevProps: Props) {
    if (prevProps.chatId !== this.props.chatId) this.getChannelMembers();
  }

  getChannelMembers = () => {
    this.props.dispatch(getChannelMembers(this.props.chatId));
  };

  renderChatName() {
    let {chat, chatType, user, theme} = this.props;
    return (
      <Text style={[styles.name, {color: theme.foregroundColor}]}>
        {chatType === 'channel'
          ? chat.name
          : user.profile.display_name_normalized || user.profile.real_name_normalized}


type Props = ReturnType<typeof mapStateToProps> &
  ThemeInjectedProps &
  DispatchProp<any> &
  StyleSheetInjectedProps & {
    chatId?: string;
    onDismiss(): void; // when using in landscape next to chat ui.
  };


componentDidMount() {
    this.getChannelMembers();
  }


componentDidUpdate(prevProps: Props) {
    if (prevProps.chatId !== this.props.chatId) this.getChannelMembers();
  }


renderChatName() {
    let {chat, chatType, user, theme} = this.props;
    return (
      <Text style={[styles.name, {color: theme.foregroundColor}]}>
        {chatType === 'channel'
          ? chat.name
          : user.profile.display_name_normalized || user.profile.real_name_normalized}


() => {
    const buffer = new BufferQueue<number>(3);
    expect(buffer.peek()).toBeUndefined();
    buffer.push(1);
    expect(buffer.peek()).toBe(1);
    buffer.push(2, 3);
    expect(buffer.peek()).toBe(1);
    expect(buffer.pop()).toBe(1);
    expect(buffer.pop()).toBe(2);
    expect(buffer.pop()).toBe(3);
    expect(buffer.pop()).toBeUndefined();
    expect(buffer.peek()).toBeUndefined();
}


() => {
    const buffer = new BufferQueue<number>(5);
    buffer.push(1, 2, 3, 4, 5);
    expect(buffer.peek()).toBe(1);
    buffer.push(6, 7); // buffer overflow
    expect(buffer['buffer']).toEqual([6, 7, 3, 4, 5]);
    expect(buffer.peek()).toBe(3);
}


() => {
    const buffer = new BufferQueue<number>(5);
    buffer.push(1, 2, 3);
    expect(buffer.flatten())
        .toEqual([1, 2, 3]);
    buffer.push(4, 5, 6, 7); // overflow
    expect(buffer.flatten()).toEqual([3, 4, 5, 6, 7]);
}


() => {
    const buffer = new BufferQueue<number>(5);
    expect(buffer.isEmpty()).toBeTruthy();
    buffer.push(1);
    expect(buffer.isEmpty()).toBeFalsy();
    buffer.pop();
    expect(buffer.isEmpty()).toBeTruthy();
}


() => {
    const buffer = new BufferQueue<number>(5);
    buffer.push(1, 2, 3, 4);
    expect(buffer.isEmpty()).toBeFalsy();
    buffer.clear();
    expect(buffer.isEmpty()).toBeTruthy();
    expect(buffer.peek()).toBeUndefined();
}


() => {
    const buffer = new BufferQueue<number>(5);
    buffer.push(1);
    expect(buffer.size()).toBe(1);
    buffer.push(2, 3, 4);
    expect(buffer.size()).toBe(4);
    buffer.push(5);
    expect(buffer.size()).toBe(5);

    buffer.push(6, 7, 8);
    expect(buffer.size()).toBe(5);

    buffer.pop();
    buffer.pop();
    expect(buffer.size()).toBe(3);
    buffer.push(9, 10, 11, 12);
    expect(buffer.size()).toBe(5);
}


@Component({
  selector: 'customerOrder-list',
  template: template,
  inputs:['parent', 'embedded'],
  providers:[CustomerOrderService],
  directives: [OrderItemListComponent,CustomerOrderDetailComponent, ROUTER_DIRECTIVES]
})
export class CustomerOrderListComponent extends BaseListComponent<CustomerOrder> implements OnInit {

  @Input()
  customerOrderList:CustomerOrder[];

  customerOrder:CustomerOrder;
  errorMessage:string;

  constructor(
  //  private _router: Router,
  protected _customerOrderService:CustomerOrderService) { super(_customerOrderService); }

  setRecords( customerOrder:CustomerOrder[]){this.customerOrderList = customerOrder;}
  getRecords():CustomerOrder[]{return this.customerOrderList;}

  ngOnInit() {
  	super.getBaseEntitys()
  }

  getEmbedded():boolean{ return this.embedded}

  setRecord( customerOrder:CustomerOrder){this.customerOrder = customerOrder;}
  getRecord():CustomerOrder{return this.customerOrder;}

  setViewRecord(customerOrder:CustomerOrder){  }

  createInstance():CustomerOrder { return <CustomerOrder>{}; }
  getSuccessUrl():string { return 'CustomerOrders'}

//  gotoDetail() {this._router.navigate(['CustomerOrderDetail', { id: this.selectedCustomerOrder.id }]);}
}


setRecords( customerOrder:CustomerOrder[]){this.customerOrderList = customerOrder;}


getRecords():CustomerOrder[]{return this.customerOrderList;}


ngOnInit() {
  	super.getBaseEntitys()
  }


getEmbedded():boolean{ return this.embedded}


setRecord( customerOrder:CustomerOrder){this.customerOrder = customerOrder;}


getRecord():CustomerOrder{return this.customerOrder;}


setViewRecord(customerOrder:CustomerOrder){  }


createInstance():CustomerOrder { return <CustomerOrder>{}; }


getSuccessUrl():string { return 'CustomerOrders'}


function createInterpreterDisplay(filters: IInterpreterStatusbarVisibilityFilter[] = []) {
        interpreterDisplay = new InterpreterDisplay(serviceContainer.object, filters);
    }


function setupWorkspaceFolder(resource: Uri, workspaceFolder?: Uri) {
        if (workspaceFolder) {
            const mockFolder = TypeMoq.Mock.ofType<WorkspaceFolder>();
            mockFolder.setup((w) => w.uri).returns(() => workspaceFolder);
            workspaceService
                .setup((w) => w.getWorkspaceFolder(TypeMoq.It.isValue(resource)))
                .returns(() => mockFolder.object);
        } else {
            workspaceService.setup((w) => w.getWorkspaceFolder(TypeMoq.It.isValue(resource))).returns(() => undefined);
        }
    }


() => {
        serviceContainer = TypeMoq.Mock.ofType<IServiceContainer>();
        workspaceService = TypeMoq.Mock.ofType<IWorkspaceService>();
        applicationShell = TypeMoq.Mock.ofType<IApplicationShell>();
        interpreterService = TypeMoq.Mock.ofType<IInterpreterService>();
        virtualEnvMgr = TypeMoq.Mock.ofType<IVirtualEnvironmentManager>();
        fileSystem = TypeMoq.Mock.ofType<IFileSystem>();
        interpreterHelper = TypeMoq.Mock.ofType<IInterpreterHelper>();
        disposableRegistry = [];
        statusBar = TypeMoq.Mock.ofType<StatusBarItem>();
        pythonSettings = TypeMoq.Mock.ofType<IPythonSettings>();
        configurationService = TypeMoq.Mock.ofType<IConfigurationService>();
        pathUtils = TypeMoq.Mock.ofType<IPathUtils>();
        output = TypeMoq.Mock.ofType<IOutputChannel>();
        autoSelection = mock(InterpreterAutoSelectionService);

        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IOutputChannel), STANDARD_OUTPUT_CHANNEL))
            .returns(() => output.object);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IWorkspaceService)))
            .returns(() => workspaceService.object);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IApplicationShell)))
            .returns(() => applicationShell.object);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IInterpreterService)))
            .returns(() => interpreterService.object);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IVirtualEnvironmentManager)))
            .returns(() => virtualEnvMgr.object);
        serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fileSystem.object);
        serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IDisposableRegistry))).returns(() => disposableRegistry);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IConfigurationService)))
            .returns(() => configurationService.object);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IInterpreterHelper)))
            .returns(() => interpreterHelper.object);
        serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IPathUtils))).returns(() => pathUtils.object);
        serviceContainer
            .setup((c) => c.get(TypeMoq.It.isValue(IInterpreterAutoSelectionService)))
            .returns(() => instance(autoSelection));

        applicationShell
            .setup((a) => a.createStatusBarItem(TypeMoq.It.isValue(StatusBarAlignment.Left), TypeMoq.It.isValue(100)))
            .returns(() => statusBar.object);
        pathUtils.setup((p) => p.getDisplayName(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((p) => p);
        createInterpreterDisplay();
    }


(c) => c.get(TypeMoq.It.isValue(IOutputChannel), STANDARD_OUTPUT_CHANNEL)


() => output.object


(c) => c.get(TypeMoq.It.isValue(IWorkspaceService))


() => workspaceService.object


(c) => c.get(TypeMoq.It.isValue(IApplicationShell))


() => applicationShell.object


(c) => c.get(TypeMoq.It.isValue(IInterpreterService))


() => interpreterService.object


(c) => c.get(TypeMoq.It.isValue(IVirtualEnvironmentManager))


() => virtualEnvMgr.object


(c) => c.get(TypeMoq.It.isValue(IFileSystem))


() => fileSystem.object


(c) => c.get(TypeMoq.It.isValue(IDisposableRegistry))


() => disposableRegistry


(c) => c.get(TypeMoq.It.isValue(IConfigurationService))


() => configurationService.object


(c) => c.get(TypeMoq.It.isValue(IInterpreterHelper))


() => interpreterHelper.object


(c) => c.get(TypeMoq.It.isValue(IPathUtils))


() => pathUtils.object


(c) => c.get(TypeMoq.It.isValue(IInterpreterAutoSelectionService))


() => instance(autoSelection)


(a) => a.createStatusBarItem(TypeMoq.It.isValue(StatusBarAlignment.Left), TypeMoq.It.isValue(100))


() => statusBar.object


(p) => p.getDisplayName(TypeMoq.It.isAny(), TypeMoq.It.isAny())


(w) => w.uri


() => workspaceFolder


(w) => w.getWorkspaceFolder(TypeMoq.It.isValue(resource))


() => mockFolder.object


() => {
        statusBar.verify((s) => (s.command = TypeMoq.It.isValue('python.setInterpreter')), TypeMoq.Times.once());
        expect(disposableRegistry).to.be.lengthOf.above(0);
        expect(disposableRegistry).contain(statusBar.object);
    }


(s) => (s.command = TypeMoq.It.isValue('python.setInterpreter'))


async () => {
        const resource = Uri.file('x');
        const workspaceFolder = Uri.file('workspace');
        const activeInterpreter: PythonEnvironment = {
            ...info,
            displayName: 'Dummy_Display_Name',
            envType: EnvironmentType.Unknown,
            path: path.join('user', 'development', 'env', 'bin', 'python')
        };
        setupWorkspaceFolder(resource, workspaceFolder);
        when(autoSelection.autoSelectInterpreter(anything())).thenResolve();
        interpreterService
            .setup((i) => i.getInterpreters(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve([]));
        interpreterService
            .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve(activeInterpreter));

        await interpreterDisplay.refresh(resource);

        verify(autoSelection.autoSelectInterpreter(anything())).once();
        statusBar.verify((s) => (s.text = TypeMoq.It.isValue(activeInterpreter.displayName)!), TypeMoq.Times.once());
        statusBar.verify((s) => (s.tooltip = TypeMoq.It.isValue(activeInterpreter.path)!), TypeMoq.Times.atLeastOnce());
    }


(i) => i.getInterpreters(TypeMoq.It.isValue(workspaceFolder))


() => Promise.resolve([])


(i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder))


() => Promise.resolve(activeInterpreter)


(s) => (s.text = TypeMoq.It.isValue(activeInterpreter.displayName)!)


(s) => (s.tooltip = TypeMoq.It.isValue(activeInterpreter.path)!)


async () => {
        const resource = Uri.file('x');
        const workspaceFolder = Uri.file('workspace');
        const activeInterpreter: PythonEnvironment = {
            ...info,
            displayName: 'Dummy_Display_Name',
            envType: EnvironmentType.Unknown,
            path: path.join('user', 'development', 'env', 'bin', 'python')
        };
        pathUtils
            .setup((p) => p.getDisplayName(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
            .returns(() => activeInterpreter.path);
        setupWorkspaceFolder(resource, workspaceFolder);
        when(autoSelection.autoSelectInterpreter(anything())).thenResolve();
        interpreterService
            .setup((i) => i.getInterpreters(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve([]));
        interpreterService
            .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve(activeInterpreter));
        output
            .setup((o) => o.appendLine(Interpreters.pythonInterpreterPath().format(activeInterpreter.path)))
            .returns(() => undefined)
            .verifiable(TypeMoq.Times.once());

        await interpreterDisplay.refresh(resource);

        output.verifyAll();
    }


() => activeInterpreter.path


(o) => o.appendLine(Interpreters.pythonInterpreterPath().format(activeInterpreter.path))


async () => {
        const resource = Uri.file('x');
        const pythonPath = path.join('user', 'development', 'env', 'bin', 'python');
        const workspaceFolder = Uri.file('workspace');
        const displayName = 'This is the display name';

        setupWorkspaceFolder(resource, workspaceFolder);
        const pythonInterpreter: PythonEnvironment = ({
            displayName,
            path: pythonPath
        } as any) as PythonEnvironment;
        interpreterService
            .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve(pythonInterpreter));

        await interpreterDisplay.refresh(resource);

        statusBar.verify((s) => (s.tooltip = TypeMoq.It.isValue(pythonPath)), TypeMoq.Times.atLeastOnce());
        statusBar.verify((s) => (s.text = TypeMoq.It.isValue(displayName)), TypeMoq.Times.once());
    }


() => Promise.resolve(pythonInterpreter)


(s) => (s.tooltip = TypeMoq.It.isValue(pythonPath))


(s) => (s.text = TypeMoq.It.isValue(displayName))


async () => {
        const resource = Uri.file('x');
        const pythonPath = path.join('user', 'development', 'env', 'bin', 'python');
        const workspaceFolder = Uri.file('workspace');
        setupWorkspaceFolder(resource, workspaceFolder);
        // tslint:disable-next-line:no-any
        interpreterService
            .setup((i) => i.getInterpreters(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve([{} as any]));
        interpreterService
            .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder)))
            .returns(() => Promise.resolve(undefined));
        configurationService.setup((c) => c.getSettings(TypeMoq.It.isAny())).returns(() => pythonSettings.object);
        pythonSettings.setup((p) => p.pythonPath).returns(() => pythonPath);
        fileSystem.setup((f) => f.fileExists(TypeMoq.It.isValue(pythonPath))).returns(() => Promise.resolve(false));
        interpreterHelper
            .setup((v) => v.getInterpreterInformation(TypeMoq.It.isValue(pythonPath)))
            .returns(() => Promise.resolve(undefined));
        virtualEnvMgr
            .setup((v) => v.getEnvironmentName(TypeMoq.It.isValue(pythonPath)))
            .returns(() => Promise.resolve(''));

        await interpreterDisplay.refresh(resource);

        statusBar.verify((s) => (s.color = TypeMoq.It.isValue('yellow')), TypeMoq.Times.once());
        statusBar.verify(
            (s) => (s.text = TypeMoq.It.isValue('$(alert) Select Python Interpreter')),
            TypeMoq.Times.once()
        );
    }


() => Promise.resolve([{} as any])


() => Promise.resolve(undefined)


(c) => c.getSettings(TypeMoq.It.isAny())


() => pythonSettings.object


(p) => p.pythonPath


() => pythonPath


(f) => f.fileExists(TypeMoq.It.isValue(pythonPath))


(v) => v.getInterpreterInformation(TypeMoq.It.isValue(pythonPath))


(v) => v.getEnvironmentName(TypeMoq.It.isValue(pythonPath))


() => Promise.resolve('')


(s) => (s.color = TypeMoq.It.isValue('yellow'))


(s) => (s.text = TypeMoq.It.isValue('$(alert) Select Python Interpreter'))


async () => {
        const workspaceFolder = Uri.file('x');
        const resource = workspaceFolder;
        const pythonPath = path.join('user', 'development', 'env', 'bin', 'python');
        const activeInterpreter: PythonEnvironment = {
            ...info,
            displayName: 'Dummy_Display_Name',
            envType: EnvironmentType.Unknown,
            companyDisplayName: 'Company Name',
            path: pythonPath
        };
        fileSystem.setup((fs) => fs.fileExists(TypeMoq.It.isAny())).returns(() => Promise.resolve(true));
        virtualEnvMgr
            .setup((v) => v.getEnvironmentName(TypeMoq.It.isValue(pythonPath)))
            .returns(() => Promise.resolve(''));
        interpreterService
            .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(resource)))
            .returns(() => Promise.resolve(activeInterpreter))
            .verifiable(TypeMoq.Times.once());
        interpreterHelper
            .setup((i) => i.getActiveWorkspaceUri(undefined))
            .returns(() => {
                return { folderUri: workspaceFolder, configTarget: ConfigurationTarget.Workspace };
            })
            .verifiable(TypeMoq.Times.once());

        await interpreterDisplay.refresh();

        interpreterHelper.verifyAll();
        interpreterService.verifyAll();
        statusBar.verify((s) => (s.text = TypeMoq.It.isValue(activeInterpreter.displayName)!), TypeMoq.Times.once());
        statusBar.verify((s) => (s.tooltip = TypeMoq.It.isValue(pythonPath)!), TypeMoq.Times.atLeastOnce());
    }


(fs) => fs.fileExists(TypeMoq.It.isAny())


(i) => i.getActiveInterpreter(TypeMoq.It.isValue(resource))


(i) => i.getActiveWorkspaceUri(undefined)


() => {
                return { folderUri: workspaceFolder, configTarget: ConfigurationTarget.Workspace };
            }


(s) => (s.tooltip = TypeMoq.It.isValue(pythonPath)!)


() => {
        const resource = Uri.file('x');
        setup(() => {
            const workspaceFolder = Uri.file('workspace');
            const activeInterpreter: PythonEnvironment = {
                ...info,
                displayName: 'Dummy_Display_Name',
                envType: EnvironmentType.Unknown,
                path: path.join('user', 'development', 'env', 'bin', 'python')
            };
            setupWorkspaceFolder(resource, workspaceFolder);
            when(autoSelection.autoSelectInterpreter(anything())).thenResolve();
            interpreterService
                .setup((i) => i.getInterpreters(TypeMoq.It.isValue(workspaceFolder)))
                .returns(() => Promise.resolve([]));
            interpreterService
                .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder)))
                .returns(() => Promise.resolve(activeInterpreter));
        });
        test('Status bar must be displayed', async () => {
            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());
        });
        test('Status bar must not be displayed if a filter is registered that needs it to be hidden', async () => {
            const filter1: IInterpreterStatusbarVisibilityFilter = { hidden: true };
            const filter2: IInterpreterStatusbarVisibilityFilter = { hidden: false };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());
        });
        test('Status bar must not be displayed if both filters need it to be hidden', async () => {
            const filter1: IInterpreterStatusbarVisibilityFilter = { hidden: true };
            const filter2: IInterpreterStatusbarVisibilityFilter = { hidden: true };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());
        });
        test('Status bar must be displayed if both filter needs it to be displayed', async () => {
            const filter1: IInterpreterStatusbarVisibilityFilter = { hidden: false };
            const filter2: IInterpreterStatusbarVisibilityFilter = { hidden: false };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());
        });
        test('Status bar must hidden if a filter triggers need for status bar to be hidden', async () => {
            const event1 = new EventEmitter<void>();
            const filter1: ReadWrite<IInterpreterStatusbarVisibilityFilter> = { hidden: false, changed: event1.event };
            const event2 = new EventEmitter<void>();
            const filter2: ReadWrite<IInterpreterStatusbarVisibilityFilter> = { hidden: false, changed: event2.event };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());

            // Filter one will now want the status bar to get hidden.
            statusBar.reset();
            filter1.hidden = true;
            event1.fire();

            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());

            // Filter two now needs it to be displayed.
            statusBar.reset();
            event2.fire();

            // No changes.
            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());

            // Filter two now needs it to be displayed & filter 1 will allow it to be displayed.
            filter1.hidden = false;
            statusBar.reset();
            event2.fire();

            // No changes.
            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());
        });
    }


() => {
            const workspaceFolder = Uri.file('workspace');
            const activeInterpreter: PythonEnvironment = {
                ...info,
                displayName: 'Dummy_Display_Name',
                envType: EnvironmentType.Unknown,
                path: path.join('user', 'development', 'env', 'bin', 'python')
            };
            setupWorkspaceFolder(resource, workspaceFolder);
            when(autoSelection.autoSelectInterpreter(anything())).thenResolve();
            interpreterService
                .setup((i) => i.getInterpreters(TypeMoq.It.isValue(workspaceFolder)))
                .returns(() => Promise.resolve([]));
            interpreterService
                .setup((i) => i.getActiveInterpreter(TypeMoq.It.isValue(workspaceFolder)))
                .returns(() => Promise.resolve(activeInterpreter));
        }


async () => {
            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());
        }


(s) => s.show()


(s) => s.hide()


async () => {
            const filter1: IInterpreterStatusbarVisibilityFilter = { hidden: true };
            const filter2: IInterpreterStatusbarVisibilityFilter = { hidden: false };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());
        }


async () => {
            const filter1: IInterpreterStatusbarVisibilityFilter = { hidden: true };
            const filter2: IInterpreterStatusbarVisibilityFilter = { hidden: true };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());
        }


async () => {
            const filter1: IInterpreterStatusbarVisibilityFilter = { hidden: false };
            const filter2: IInterpreterStatusbarVisibilityFilter = { hidden: false };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());
        }


async () => {
            const event1 = new EventEmitter<void>();
            const filter1: ReadWrite<IInterpreterStatusbarVisibilityFilter> = { hidden: false, changed: event1.event };
            const event2 = new EventEmitter<void>();
            const filter2: ReadWrite<IInterpreterStatusbarVisibilityFilter> = { hidden: false, changed: event2.event };
            createInterpreterDisplay([filter1, filter2]);

            await interpreterDisplay.refresh(resource);

            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());

            // Filter one will now want the status bar to get hidden.
            statusBar.reset();
            filter1.hidden = true;
            event1.fire();

            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());

            // Filter two now needs it to be displayed.
            statusBar.reset();
            event2.fire();

            // No changes.
            statusBar.verify((s) => s.show(), TypeMoq.Times.never());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.once());

            // Filter two now needs it to be displayed & filter 1 will allow it to be displayed.
            filter1.hidden = false;
            statusBar.reset();
            event2.fire();

            // No changes.
            statusBar.verify((s) => s.show(), TypeMoq.Times.once());
            statusBar.verify((s) => s.hide(), TypeMoq.Times.never());
        }


() =>
    showConfirmationModalAction({
      title: 'Errors',
      heading: 'There are errors or missing required fields on the page',
      confirmButtonText: 'OK'
    })


() => {
    const { validatePage, setSectionStatus, section, showPageErrorsMessage } = this.props;

    // skip if no section exists - user has to implement own button bar with validation
    if (!section) {
      // let button bar know if it should auto navigate
      return false;
    }

    if (validatePage() === false) {
      showPageErrorsMessage();
      setSectionStatus(section, EDITOR_STATUS.errors);
      return true;
    }

    setSectionStatus(section, EDITOR_STATUS.all_good);
    return true;
  }


(scrollTop: number, topperHeight: number, toolbarHeight: number) => {
    const { headerHeight } = this.state;
    if (headerHeight !== topperHeight + toolbarHeight) {
      this.setState({ headerHeight: topperHeight + toolbarHeight });
    }
  }


() => {
    const titleHeight = this.titleAreaRef ? this.titleAreaRef.scrollHeight : 0;

    this.setState({ titleHeight });
  }


(searchValue: string) => {
    this.setState({ keywordSearch: searchValue });
  }


() => {
    this.onSearchChange('');
  }


(searchValue: string) => {
    if (searchValue) {
      this.props.storeKeywordSearch(searchValue);
      this.props.history.push(`/?keyword=${searchValue}`);
    }
  }


(ref: HTMLElement | null) => {
    this.titleAreaRef = ref;
  }


() => {
    const { operator, uploads,versionEditorRootPath ,updatePackageOperatorVersion, versions } = this.props;
    const version = versionEditorRootPath.split('/').pop() as string;
    const versionMetadata = versions.find(versionMeta => versionMeta.version === version);

    updateChannelEditorOnExit(operator, uploads, version, updatePackageOperatorVersion, versionMetadata && versionMetadata.namePatternWithV);
  }


versionMeta => versionMeta.version === version


(path: string) => {
    const { history, match, resetPackage, showResetPackageConfirmationModal, hideConfirmModal } = this.props;

    showResetPackageConfirmationModal(match.params.packageName, () => {
      hideConfirmModal();
      resetPackage();
      history.push(path);
    });

    return false;
  }


() => {
      hideConfirmModal();
      resetPackage();
      history.push(path);
    }


dispatch => ({
  ...bindActionCreators(OperatorEditorSubPageActions, dispatch)
})


(state: StoreState) => ({
  sectionStatus: state.editorState.sectionStatus,
  operator: state.editorState.operator,
  uploads: state.editorState.uploads,
  versions: state.packageEditorState.operatorVersions
})


class OperatorEditorSubPage extends React.PureComponent<OperatorEditorSubPageProps, OperatorEditorSubPageState> {

  static propTypes;
  static defaultProps;

  state: OperatorEditorSubPageState = {
    headerHeight: 0,
    titleHeight: 0,
    keywordSearch: ''
  };

  onWindowResize: any;

  titleAreaRef: HTMLElement | null;

  componentDidMount() {
    const { validatePage, setSectionStatus, section, sectionStatus } = this.props;

    this.updateTitleHeight();
    this.onWindowResize = debounce(this.updateTitleHeight, 100);
    window.addEventListener('resize', this.onWindowResize);

    // do not validate pristine page
    if (section && sectionStatus[section] !== EDITOR_STATUS.empty) {
      // validate page to display errors when opened
      if (validatePage() === false) {
        setSectionStatus(section, EDITOR_STATUS.errors);
      }
    }
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.onWindowResize);
  }

  allSet = () => {
    const { validatePage, setSectionStatus, section, showPageErrorsMessage } = this.props;

    // skip if no section exists - user has to implement own button bar with validation
    if (!section) {
      // let button bar know if it should auto navigate
      return false;
    }

    if (validatePage() === false) {
      showPageErrorsMessage();
      setSectionStatus(section, EDITOR_STATUS.errors);
      return true;
    }

    setSectionStatus(section, EDITOR_STATUS.all_good);
    return true;
  };

  onScroll = (scrollTop: number, topperHeight: number, toolbarHeight: number) => {
    const { headerHeight } = this.state;
    if (headerHeight !== topperHeight + toolbarHeight) {
      this.setState({ headerHeight: topperHeight + toolbarHeight });
    }
  };

  updateTitleHeight = () => {
    const titleHeight = this.titleAreaRef ? this.titleAreaRef.scrollHeight : 0;

    this.setState({ titleHeight });
  };

  onSearchChange = (searchValue: string) => {
    this.setState({ keywordSearch: searchValue });
  };

  clearSearch = () => {
    this.onSearchChange('');
  };

  searchCallback = (searchValue: string) => {
    if (searchValue) {
      this.props.storeKeywordSearch(searchValue);
      this.props.history.push(`/?keyword=${searchValue}`);
    }
  };

  setTitleAreaRef = (ref: HTMLElement | null) => {
    this.titleAreaRef = ref;
  };

  onBackToChannelEditor = () => {
    const { operator, uploads,versionEditorRootPath ,updatePackageOperatorVersion, versions } = this.props;
    const version = versionEditorRootPath.split('/').pop() as string;
    const versionMetadata = versions.find(versionMeta => versionMeta.version === version);

    updateChannelEditorOnExit(operator, uploads, version, updatePackageOperatorVersion, versionMetadata && versionMetadata.namePatternWithV);
  };

  onPackageLeave = (path: string) => {
    const { history, match, resetPackage, showResetPackageConfirmationModal, hideConfirmModal } = this.props;

    showResetPackageConfirmationModal(match.params.packageName, () => {
      hideConfirmModal();
      resetPackage();
      history.push(path);
    });

    return false;
  };

  render() {
    const {
      history,
      header,
      title = '',
      versionEditorRootPath,
      field,
      description = null,
      children,
      pageId,
      buttonBar,
      secondary,
      lastPage,
      lastPageTitle,
      tertiary,
      pageErrors = false
    } = this.props;
    const { keywordSearch, headerHeight, titleHeight } = this.state;

    return (
      <Page
        className="oh-page-operator-editor"
        toolbarContent={
          <EditorBreadcrumbs
            sectionSubPath={lastPage}
            sectionLabel={lastPageTitle}
            history={history}
            currentLabel={title}
            versionEditorRootPath={versionEditorRootPath}
            onEditorExit={this.onBackToChannelEditor}
            onPackageLeave={this.onPackageLeave}
          />
        }
        history={history}
        searchValue={keywordSearch}
        onSearchChange={this.onSearchChange}
        clearSearch={this.clearSearch}
        searchCallback={this.searchCallback}
        scrollCallback={this.onScroll}
      >

          <div className="oh-operator-editor-page__title-area" ref={this.setTitleAreaRef} style={


interface OperatorEditorSubPageState {
  headerHeight: number
  titleHeight: number
  keywordSearch: string
}


export type OperatorEditorSubPageProps = {
  history: History,
  match: match<{packageName: string}>
  versionEditorRootPath: string,
  title?: React.ReactElement | string
  description?: React.ReactNode
  field?: string
  header?: React.ReactNode
  buttonBar?: React.ReactNode
  secondary?: boolean
  pageId?: string
  tertiary?: boolean
  lastPage?: string
  lastPageTitle?: string
  section?: EditorSectionNames
  pageErrors?: boolean
  validatePage: () => boolean
} & ReturnType<typeof mapStateToProps> & typeof OperatorEditorSubPageActions;


componentDidMount() {
    const { validatePage, setSectionStatus, section, sectionStatus } = this.props;

    this.updateTitleHeight();
    this.onWindowResize = debounce(this.updateTitleHeight, 100);
    window.addEventListener('resize', this.onWindowResize);

    // do not validate pristine page
    if (section && sectionStatus[section] !== EDITOR_STATUS.empty) {
      // validate page to display errors when opened
      if (validatePage() === false) {
        setSectionStatus(section, EDITOR_STATUS.errors);
      }
    }
  }


componentWillUnmount() {
    window.removeEventListener('resize', this.onWindowResize);
  }


render() {
    const {
      history,
      header,
      title = '',
      versionEditorRootPath,
      field,
      description = null,
      children,
      pageId,
      buttonBar,
      secondary,
      lastPage,
      lastPageTitle,
      tertiary,
      pageErrors = false
    } = this.props;
    const { keywordSearch, headerHeight, titleHeight } = this.state;

    return (
      <Page
        className="oh-page-operator-editor"
        toolbarContent={
          <EditorBreadcrumbs
            sectionSubPath={lastPage}
            sectionLabel={lastPageTitle}
            history={history}
            currentLabel={title}
            versionEditorRootPath={versionEditorRootPath}
            onEditorExit={this.onBackToChannelEditor}
            onPackageLeave={this.onPackageLeave}
          />
        }


function RequiredIf(cb: any): PropertyDecorator {
  return JsonEntityFn((store, [target, propertyKey]) => {
    BeforeDeserialize((data) => {
      if (!cb(data[propertyKey], data)) {
        throw new BadRequest(`${String(propertyKey)} is required`);
      }
      return data;
    })(target);
  });
}


(value: any, data: any) => data.name === "tsed" && value !== undefined


(store, [target, propertyKey]) => {
    BeforeDeserialize((data) => {
      if (!cb(data[propertyKey], data)) {
        throw new BadRequest(`${String(propertyKey)} is required`);
      }
      return data;
    })(target);
  }


(data) => {
      if (!cb(data[propertyKey], data)) {
        throw new BadRequest(`${String(propertyKey)} is required`);
      }
      return data;
    }


() => {
  it("should deserialize object correctly", async () => {
    // GIVEN
    const company = {
      name: "tsed",
      location: "Paris"
    };

    // WHEN
    const companyAfterDeserialization = deserialize(company, {type: Company});

    // THEN
    expect(companyAfterDeserialization).toEqual({
      name: "tsed",
      location: "Paris"
    });
  });

  it("should try to deserialize and throw a bad request error", async () => {
    // GIVEN
    const company = {
      name: "tsed"
    };

    // WHEN
    const badRequestError = await catchAsyncError(() => deserialize(company, {type: Company}));

    // THEN
    expect(badRequestError).toBeInstanceOf(BadRequest);
  });
}


async () => {
    // GIVEN
    const company = {
      name: "tsed",
      location: "Paris"
    };

    // WHEN
    const companyAfterDeserialization = deserialize(company, {type: Company});

    // THEN
    expect(companyAfterDeserialization).toEqual({
      name: "tsed",
      location: "Paris"
    });
  }


async () => {
    // GIVEN
    const company = {
      name: "tsed"
    };

    // WHEN
    const badRequestError = await catchAsyncError(() => deserialize(company, {type: Company}));

    // THEN
    expect(badRequestError).toBeInstanceOf(BadRequest);
  }


() => deserialize(company, {type: Company})


class Company {
  @Property()
  name: string;
  @Property()
  @RequiredIf((value: any, data: any) => data.name === "tsed" && value !== undefined)
  location: string;
}