    uint64_t IndexScale = 0;
    uint64_t IndexOffset = 0;

    // If we're scaling a smaller permute op, then we need to repeat the
    // indices, scaling and offsetting them as well.
    // e.g. v4i32 -> v16i8 (Scale = 4)
    // IndexScale = v4i32 Splat(4 << 24 | 4 << 16 | 4 << 8 | 4)
    // IndexOffset = v4i32 Splat(3 << 24 | 2 << 16 | 1 << 8 | 0)
    for (uint64_t i = 0; i != Scale; ++i) {
      IndexScale |= Scale << (i * NumDstBits);
      IndexOffset |= i << (i * NumDstBits);
    }

    Idx = DAG.getNode(ISD::MUL, SDLoc(Idx), SrcVT, Idx,
                      DAG.getConstant(IndexScale, SDLoc(Idx), SrcVT));
    Idx = DAG.getNode(ISD::ADD, SDLoc(Idx), SrcVT, Idx,
                      DAG.getConstant(IndexOffset, SDLoc(Idx), SrcVT));
    return Idx;
  };

  unsigned Opcode = 0;
  switch (VT.SimpleTy) {
  default:
    break;
  case MVT::v16i8:
    if (Subtarget.hasSSSE3())
      Opcode = X86ISD::PSHUFB;
    break;
  case MVT::v8i16:
    if (Subtarget.hasVLX() && Subtarget.hasBWI())
      Opcode = X86ISD::VPERMV;
    else if (Subtarget.hasSSSE3()) {
      Opcode = X86ISD::PSHUFB;
      ShuffleVT = MVT::v16i8;
    }
    break;
  case MVT::v4f32:
  case MVT::v4i32:
    if (Subtarget.hasAVX()) {
      Opcode = X86ISD::VPERMILPV;
      ShuffleVT = MVT::v4f32;
    } else if (Subtarget.hasSSSE3()) {
      Opcode = X86ISD::PSHUFB;
      ShuffleVT = MVT::v16i8;
    }
    break;
  case MVT::v2f64:
  case MVT::v2i64:
    if (Subtarget.hasAVX()) {
      // VPERMILPD selects using bit#1 of the index vector, so scale IndicesVec.
      IndicesVec = DAG.getNode(ISD::ADD, DL, IndicesVT, IndicesVec, IndicesVec);
      Opcode = X86ISD::VPERMILPV;
      ShuffleVT = MVT::v2f64;
    } else if (Subtarget.hasSSE41()) {
      // SSE41 can compare v2i64 - select between indices 0 and 1.
      return DAG.getSelectCC(
          DL, IndicesVec,
          getZeroVector(IndicesVT.getSimpleVT(), Subtarget, DAG, DL),
          DAG.getVectorShuffle(VT, DL, SrcVec, SrcVec, {0, 0}),
          DAG.getVectorShuffle(VT, DL, SrcVec, SrcVec, {1, 1}),
          ISD::CondCode::SETEQ);
    }
    break;
  case MVT::v32i8:
    if (Subtarget.hasVLX() && Subtarget.hasVBMI())
      Opcode = X86ISD::VPERMV;
    else if (Subtarget.hasXOP()) {
      SDValue LoSrc = extract128BitVector(SrcVec, 0, DAG, DL);
      SDValue HiSrc = extract128BitVector(SrcVec, 16, DAG, DL);
      SDValue LoIdx = extract128BitVector(IndicesVec, 0, DAG, DL);
      SDValue HiIdx = extract128BitVector(IndicesVec, 16, DAG, DL);
      return DAG.getNode(
          ISD::CONCAT_VECTORS, DL, VT,
          DAG.getNode(X86ISD::VPPERM, DL, MVT::v16i8, LoSrc, HiSrc, LoIdx),
          DAG.getNode(X8


 UpdateStoreActions<T, this>;

  path<K1 extends keyof T>(k1: K1): UpdateStoreActions<T[K1], this>;

  path<K1 extends keyof T, K2 extends keyof T[K1]>(
    k1: K1,
    k2: K2,
  ): UpdateStoreActions<T[K1][K2], this>;

  path<
    K1 extends keyof NonNullable<T>,
    K2 extends keyof NonNullable<NonNullable<T>[K1]>,
    K3 extends keyof NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>
  >(
    k1: K1,
    k2: K2,
    k3: K3,
  ): UpdateStoreActions<
    NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3],
    this
  >;

  path<
    K1 extends keyof NonNullable<T>,
    K2 extends keyof NonNullable<NonNullable<T>[K1]>,
    K3 extends keyof NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>,
    K4 extends keyof NonNullable<
      NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]
    >
  >(
    k1: K1,
    k2: K2,
    k3: K3,
    k4: K4,
  ): UpdateStoreActions<
    NonNullable<NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]>[K4],
    this
  >;

  path<
    K1 extends keyof NonNullable<T>,
    K2 extends keyof NonNullable<NonNullable<T>[K1]>,
    K3 extends keyof NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>,
    K4 extends keyof NonNullable<
      NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]
    >,
    K5 extends keyof NonNullable<
      NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]
    >[K4]
  >(
    k1: K1,
    k2: K2,
    k3: K3,
    k4: K4,
    k5: K5,
  ): UpdateStoreActions<
    NonNullable<
      NonNullable<NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]>[K4]
    >[K5],
    this
  >;

  path<
    K1 extends keyof NonNullable<T>,
    K2 extends keyof NonNullable<NonNullable<T>[K1]>,
    K3 extends keyof NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>,
    K4 extends keyof NonNullable<
      NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]
    >,
    K5 extends keyof NonNullable<
      NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]
    >[K4],
    K6 extends keyof NonNullable<
      NonNullable<NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]>[K4]
    >[K5]
  >(
    k1: K1,
    k2: K2,
    k3: K3,
    k4: K4,
    k5: K5,
    k6: K6,
  ): UpdateStoreActions<
    NonNullable<
      NonNullable<NonNullable<NonNullable<NonNullable<T>[K1]>[K2]>[K3]>[K4]
    >[K5][K6],
    this
  >;

  path(...keys: string[]) {
    const path = keys.join('.');

    const savedActions = this.actionCache.get(path);
    if (savedActions) return savedActions;

    const clearNestedStore = () => this.nestedStores.delete(path);
    // TODO Maybe return the current stored value in updateData if it has been set instead of original
    const originalValue = (): any => {
      if (path === '') return this.getData();
      return keys.reduce(
        // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
        // @ts-ignore
        (result, key) => (result ?? {})[key],
        this.getData() as JsonObject,
      );
    };

    const store = (newVal: ValOrValFN<NonFunction>) => {


lClassName = classInjectData.getFullClassName();
            let dic = MVCInject.InjectDefMapping[fullClassName];
            if (!dic) {
                fullClassName = MVCInject.InjectShortNameMapping[fullClassName];
                dic = MVCInject.InjectDefMapping[fullClassName];
            }
            if (!dic) {
                return null;
            }
            let def = dic[property];
            let cls = Singleton.GetClass(def);
            if (cls == null) {
                let nsList = fullClassName.split(".");
                let len = nsList.length;
				/**
				 * 从后往前加名称空间(eg:game,lingyu.game,com.lingyu.game)
				 */
                for (let i = len - 2; i > -1; i--) {
                    def = nsList[i] + "." + def;
                    cls = Singleton.GetClass(def);
                    if (cls) {
                        break;
                    }
                }
            }
            return cls;
        }
        public inject(target: IInjectable): IInjectable {
            let type = Object.getPrototypeOf(target);
            while (type) {
                let item=InjectAttribute.Get(type);
                if(item)this.doInject(item, target);

                //循环找基类注入
                type = Object.getPrototypeOf(type);
            }
            return target;
        }
        protected doInject(classInjectData: InjectClassData, target: IInjectable) {
            for (let key in classInjectData.propertys) {
                let cls = this.getInjectClassByDef(classInjectData, key);
                if (cls == null) {
                    DebugX.LogError(target, key, "注入的类型找不到:" + classInjectData.getFullClassName());
                    continue;
                }
                let o = this.autoMVC(cls);
                if (!o) {
                    continue;
                }
                target[key] = o;
                if (key == "view" && ("setView" in target)) {
                    (<IMediator>target).setView(o);
                } else if (key == "proxy" && ("setProxy" in target)) {
                    (<IMediator>target).setProxy(o);
                }
            }
            for (let cmd in classInjectData.cmds) {
                let list = classInjectData.cmds[cmd];
                for (let item of list) {
                    SocketX.AddListener(+cmd, item, target);
                }
            }
        }
        protected autoMVC(classType:Class): any {
            let fullClassName = Singleton.GetClassFullName(classType);
            if (Singleton.IsUnique(fullClassName)) {
                return Singleton.GetInstance(fullClassName);
            }
            let aliasName = Singleton.GetAliasName(fullClassName);
            let isProxy = ReflectUtils.IsSubclassOf(classType, Proxy);
            let isMediator:boolean;
            if(isProxy){
                if(this.facade.hasProxyByName(aliasName)) {
                    return this.facade.getProxyByName(aliasName);
                }
            }else if(isMediator=ReflectUtils.IsSubclassOf(classType, Mediator)){
                if(this.facade.hasMediatorByName(aliasName)) {
                    return this.facade.getMediatorByName(aliasName);
                }
            }else{
                let ins = new classType();
                if (ins[MVCInject.INJECTABLE]) {
                    ins = this.inject(ins);
                }
                return ins;
            }
            let ins = this.facade.getInjectLock(aliasName);
            if (!ins) {
                ins = Singleton.__GetOrCreateOneInstance(aliasName);
                ins["_name"] = aliasName;
                //可注入 必须加锁 (先调用也是想让onRegister的时候


 });

    /*d3.selectAll('.highlightRow') // taken care of as they're apart of row and column groupings already
      .transition()
      .duration(transitionTime)
      .delay((d, i) => { return this.verticalScale(i) * 4; })
      .attr("transform", (d, i) => { return "translate(0," + this.verticalScale(i) + ")"; })

    d3.selectAll('.highlightCol')
      .transition()
      .duration(transitionTime)
      .delay((d, i) => { return this.verticalScale(i) * 4; })
      .attr("transform", (d, i) => { return "translate(" + this.verticalScale(i) + ")rotate(-90)"; });*/
  }
  private columnNames: { };
  /**
   * [initalizeAttributes description]
   * @return [description]
   */
  initalizeAttributes() {
    this.attributeWidth = 450 - this.margins.left - this.margins.right;
    this.attributeHeight = 600 - this.margins.top - this.margins.bottom;

    let width = this.attributeWidth + this.margins.left + this.margins.right; //+ 75;
    let height = this.attributeHeight + this.margins.top + this.margins.bottom;

    this.attributes = d3.select('#attributes').append("svg")
      .attr("viewBox", "0 0 " + width + " " + height + "")
      .attr("preserveAspectRatio", "xMinYMin meet")
      .append("g")
      .classed("svg-content", true)
      .attr('id', 'attributeMargin')
      .attr("transform", "translate(" + 0 + "," + this.margins.top + ")");

    // add zebras and highlight rows
    /*
    this.attributes.selectAll('.highlightRow')
      .data(this.nodes)
      .enter()
      .append('rect')
      .classed('highlightRow', true)
      .attr('x', 0)
      .attr('y', (d, i) => this.verticalScale(i))
      .attr('width', this.attributeWidth)
      .attr('height', this.verticalScale.bandwidth())
      .attr('fill', (d, i) => { return i % 2 == 0 ? "#fff" : "#eee" })
      */

    let barMargin = { top: 1, bottom: 1, left: 5, right: 5 }
    let barHeight = this.verticalScale.bandwidth() - barMargin.top - barMargin.bottom;

    // Draw each row (translating the y coordinate)
    this.attributeRows = this.attributes.selectAll(".row")
      .data(this.nodes)
      .enter().append("g")
      .attr("class", "row")
      .attr("transform", (d, i) => {
        return "translate(0," + this.verticalScale(i) + ")";
      });

    this.attributeRows.append("line")
      .attr("x1", 0)
      .attr("x2", this.attributeWidth)
      .attr('stroke', '2px')
      .attr('stroke-opacity', 0.3);

    this.attributeRows.append('rect')
      .attr('x', 0)
      .attr('y', 0)
      .classed('highlightAttrRow', true)
      .attr('id', (d, i) => {
        return "highlightAttrRow" + d.screen_name;
      })
      .attr('width', width)
      .attr('height', this.verticalScale.bandwidth()) // end addition
      .attr("fill-opacity", 0)
      .on('mouseover', (p: any) => {
        // selection constructor
        // selection of rows or columns
        // selection of edge or attribute
        // classing hovered as true

        console.log(p);
        // wont work for seriated matricies!
        let attrRow = this.highlightRow(p);

        /*let sel = d3.selectAll(".highlightRow")
          .filter((d, i) => {

              if(d.index != null){
                return p.index == d.index; // attr


this.NGAYPHEP,
            this.CONGNGAYLE,
            this.CONGCHUNHAT,
            this.TONGNGAYCONG});
            this.gvBangCongChiTiet.DetailHeight = 431;
            this.gvBangCongChiTiet.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus;
            this.gvBangCongChiTiet.GridControl = this.gcBangCongChiTiet;
            this.gvBangCongChiTiet.HorzScrollVisibility = DevExpress.XtraGrid.Views.Base.ScrollVisibility.Always;
            this.gvBangCongChiTiet.IndicatorWidth = 40;
            this.gvBangCongChiTiet.Name = "gvBangCongChiTiet";
            this.gvBangCongChiTiet.OptionsCustomization.AllowFilter = false;
            this.gvBangCongChiTiet.OptionsCustomization.AllowGroup = false;
            this.gvBangCongChiTiet.OptionsCustomization.AllowSort = false;
            this.gvBangCongChiTiet.OptionsDetail.EnableMasterViewMode = false;
            this.gvBangCongChiTiet.OptionsFind.AlwaysVisible = true;
            this.gvBangCongChiTiet.OptionsFind.FindNullPrompt = "Nhập nội dung cần tìm";
            this.gvBangCongChiTiet.OptionsMenu.EnableColumnMenu = false;
            this.gvBangCongChiTiet.OptionsView.ShowFilterPanelMode = DevExpress.XtraGrid.Views.Base.ShowFilterPanelMode.Never;
            this.gvBangCongChiTiet.OptionsView.ShowGroupPanel = false;
            this.gvBangCongChiTiet.OptionsView.ShowIndicator = false;
            this.gvBangCongChiTiet.RowHeight = 28;
            this.gvBangCongChiTiet.VertScrollVisibility = DevExpress.XtraGrid.Views.Base.ScrollVisibility.Always;
            //
            // THONGTIN
            //
            this.THONGTIN.AppearanceHeader.Font = new System.Drawing.Font("Tahoma", 10F, System.Drawing.FontStyle.Bold);
            this.THONGTIN.AppearanceHeader.Options.UseFont = true;
            this.THONGTIN.Caption = "THÔNG TIN NHÂN VIÊN";
            this.THONGTIN.Columns.Add(this.colMaNV);
            this.THONGTIN.Columns.Add(this.colHoTen);
            this.THONGTIN.Fixed = DevExpress.XtraGrid.Columns.FixedStyle.Left;
            this.THONGTIN.Name = "THONGTIN";
            this.THONGTIN.RowCount = 2;
            this.THONGTIN.VisibleIndex = 0;
            this.THONGTIN.Width = 279;
            //
            // colMaNV
            //
            this.colMaNV.Caption = "MANV";
            this.colMaNV.FieldName = "MANV";
            this.colMaNV.Name = "colMaNV";
            this.colMaNV.OptionsColumn.AllowEdit = false;
            this.colMaNV.OptionsColumn.AllowFocus = false;
            this.colMaNV.Visible = true;
            this.colMaNV.Width = 79;
            //
            // colHoTen
            //
            this.colHoTen.Caption = "HỌ VÀ TÊN";
            this.colHoTen.FieldName = "HOTEN";
            this.colHoTen.Name = "colHoTen";
            this.colHoTen.OptionsColumn.AllowEdit = false;
            this.colHoTen.OptionsColumn.AllowFocus = false;
            this.colHoTen.OptionsColumn.FixedWidth = true;
            t


: IanaRegisteredIso639Code, language_extension: Option<LanguageExtension>, next_subtag: NextSubtagAfterLanguageExtension) -> Output
		{
			Left
			(
				(
					Language::Ordinary
					(
						OrdinaryLanguage
						{
							iana_registered_iso_639_code,

							language_extension,
						}
					),
					next_subtag
				)
			)
		}

		#[inline(always)]
		const fn left_none(iana_registered_iso_639_code: IanaRegisteredIso639Code, next_subtag: NextSubtagAfterLanguageExtension) -> Output
		{
			left(iana_registered_iso_639_code, None, next_subtag)
		}

		#[inline(always)]
		const fn left_some(iana_registered_iso_639_code: IanaRegisteredIso639Code, language_extension: LanguageExtension, next_subtag: NextSubtagAfterLanguageExtension) -> Output
		{
			left(iana_registered_iso_639_code, Some(language_extension), next_subtag)
		}

		#[inline(always)]
		const fn right<'a>(regular_grandfathered: RegularGrandfathered) -> Output<'a>
		{
			Right(IetfBcp47LanguageTag::regular_grandfathered(regular_grandfathered))
		}

		#[inline(always)]
		fn unreachable_code_because_pending_impossible() -> !
		{
			unreachable_code_const(PendingImpossibleMessage)
		}

		macro_rules! parse_extended_language_subtag
		{
			($subtags: ident, $next_subtag: ident, $ok: block) =>
			{
				match Self::parse_extended_language_subtag(subtags)?
				{
					Right(language_extension) => language_extension,

					Left($next_subtag) => return Ok($ok),
				}
			}
		}

		let language_extension_0 = parse_extended_language_subtag!(subtags, next_subtag,
		{
			debug_assert_ne!(next_subtag, Pending, "{}", PendingImpossibleMessage);
			left_none(iana_registered_iso_639_code, next_subtag)
		});

		let language_extension_1 = parse_extended_language_subtag!(subtags, next_subtag,
		{
			match (next_subtag, iana_registered_iso_639_code, language_extension_0)
			{
				(Exhausted, no, bok) => right(no_bok),

				(Exhausted, no, nyn) => right(no_nyn),

				(Exhausted, zh, min) => right(zh_min),

				(Pending, _, _) => unreachable_code_because_pending_impossible(),

				(next_subtag @ _, _, _) => left_some(iana_registered_iso_639_code, Self::new_language_extension_0(language_extension_0), next_subtag),
			}
		});

		let language_extension_2 = parse_extended_language_subtag!(subtags, next_subtag,
		{
			match (next_subtag, iana_registered_iso_639_code, language_extension_0, language_extension_1)
			{
				(Exhausted, zh, min, nan) => right(zh_min_nan),

				(Pending, _, _, _) => unreachable_code_because_pending_impossible(),

				(next_subtag @ _, _, _, _) => left_some(iana_registered_iso_639_code, Self::new_language_extension_1(language_extension_0, language_extension_1), next_subtag),
			}
		});

		Ok(left_some(iana_registered_iso_639_code, Self::new_language_extension_2(language_extension_0, language_extension_1, language_extens


}
package io.neoterm.component.extrakey

import io.neolang.frontend.ConfigVisitor
import io.neoterm.component.ConfigFileBasedObject
import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
import io.neoterm.frontend.session.view.extrakey.IExtraButton
import io.neoterm.frontend.session.view.extrakey.TextButton

/**
 * @author kiva
 */
class NeoExtraKey : ConfigFileBasedObject {
  companion object {
    const val EKS_META_CONTEXT_NAME = "extra-key"

    const val EKS_META_PROGRAM = "program"
    const val EKS_META_KEY = "key"
    const val EKS_META_WITH_DEFAULT = "with-default"
    const val EKS_META_WITH_ENTER = "with-enter"
    const val EKS_META_DISPLAY = "display"
    const val EKS_META_CODE = "code"
    const val EKS_META_VERSION = "version"

    val EKS_META_CONTEXT_PATH = arrayOf(EKS_META_CONTEXT_NAME)
  }

  var version: Int = 0
  val programNames: MutableList<String> = mutableListOf()
  val shortcutKeys: MutableList<IExtraButton> = mutableListOf()
  var withDefaultKeys: Boolean = true

  fun applyExtraKeys(extraKeysView: ExtraKeysView) {
    if (withDefaultKeys) {
      extraKeysView.loadDefaultUserKeys()
    }
    for (button in shortcutKeys) {
      extraKeysView.addUserKey(button)
    }
  }

  override fun onConfigLoaded(configVisitor: ConfigVisitor) {
    // program
    val programArray = configVisitor.getArray(EKS_META_CONTEXT_PATH, EKS_META_PROGRAM)
    if (programArray.isEmpty()) {
      throw RuntimeException("Extra Key must have programs attribute")
    }

    programArray.forEach {
      if (!it.isBlock()) {
        programNames.add(it.eval().asString())
      }
    }

    // key
    val keyArray = configVisitor.getArray(EKS_META_CONTEXT_PATH, EKS_META_KEY)
    keyArray.takeWhile { it.isBlock() }
      .forEach {
        val display = it.eval(EKS_META_DISPLAY)
        val code = it.eval(EKS_META_CODE)
        if (!code.isValid()) {
          throw RuntimeException("Key must have a code")
        }

        val codeText = code.asString()
        val displayText = if (display.isValid()) display.asString() else codeText
        val withEnter = it.eval(EKS_META_WITH_ENTER)
        val withEnterBoolean = withEnter.asString() == "true"

        val button = TextButton(codeText, withEnterBoolean)
        button.displayText = displayText
        shortcutKeys.add(button)
      }

    // We must cal toDouble() before toInt()
    // Because in NeoLang, numbers are default to Double
    version = getMetaByVisitor(configVisitor, EKS_META_VERSION)?.toDouble()?.toInt() ?: 0
    withDefaultKeys = "true" == getMetaByVisitor(configVisitor, EKS_META_WITH_DEFAULT)
  }

  private fun getMetaByVisitor(visitor: ConfigVisitor, metaName: String): String? {
    return visitor.getStringValue(EKS_META_CONTEXT_PATH, metaName)
  }
}
package io.neoterm.component.colorscheme

import android.content.Context
import io.neolang.frontend.ConfigVisitor
import io.neoterm.App
import io.neoterm.R
import io.neoterm.component.ComponentManager
import io.neoterm.component.ConfigFileBasedComponent
import io.neoterm.component.codegen.CodeGenComponent
import io.neoterm.component.config.NeoPreference
import io.neoterm.component.config.NeoTermPath
import io.neoterm.frontend.session.view.TerminalView
import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
import io.neoterm.ut


},
		},
	} {
		t.Run(tt.name, func(t *testing.T) {
			suite := httphandlertesting.NewSuite(&httphandlertesting.Config{
				Method: http.MethodGet,
			})
			httphandler.ServeDebug(suite.GetMux(), tt.cfg, tt.handler)
			suite.Run(t, tt.cases)
		})
	}
}
/*
 * Copyright 2022 The Furiko Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package mock

import (
	"context"
	"encoding/json"
	"sync"

	"k8s.io/apimachinery/pkg/runtime"

	configv1alpha1 "github.com/furiko-io/furiko/apis/config/v1alpha1"
	"github.com/furiko-io/furiko/pkg/runtime/configloader"
	"github.com/furiko-io/furiko/pkg/runtime/controllercontext"
)

type Configs struct {
	controllercontext.Configs
	configLoader *ConfigLoader
}

// NewConfigs returns a new dynamic config manager that supports overriding a
// defaults configloader with configs from memory.
func NewConfigs() *Configs {
	mgr := configloader.NewConfigManager()
	configLoader := NewMockConfigLoader()
	mgr.AddConfigLoaders(
		configloader.NewDefaultsLoader(),
		configLoader,
	)
	return &Configs{
		Configs:      controllercontext.NewContextConfigs(mgr),
		configLoader: configLoader,
	}
}

// SetConfigs is a convenience method to set configs from a map.
func (c *Configs) SetConfigs(cfgs map[configv1alpha1.ConfigName]runtime.Object) {
	for configName, cfg := range cfgs {
		c.MockConfigLoader().SetConfig(configName, cfg)
	}
}

// MockConfigLoader returns the mock configloader.Loader.
func (c *Configs) MockConfigLoader() *ConfigLoader {
	return c.configLoader
}

var _ controllercontext.Configs = (*Configs)(nil)

type ConfigLoader struct {
	configs map[configv1alpha1.ConfigName]runtime.Object
	mu      sync.RWMutex
}

var _ configloader.Loader = (*ConfigLoader)(nil)

func NewMockConfigLoader() *ConfigLoader {
	return &ConfigLoader{
		configs: make(map[configv1alpha1.ConfigName]runtime.Object),
	}
}

func (c *ConfigLoader) Name() string {
	return "Mock"
}

func (c *ConfigLoader) Start(ctx context.Context) error {
	return nil
}

func (c *ConfigLoader) Load(configName configv1alpha1.ConfigName) (configloader.Config, error) {
	config, ok := c.configs[configName]
	if !ok {
		return nil, nil
	}
	bytes, err := json.Marshal(config)
	if err != nil {
		return nil, err
	}
	m := make(configloader.Config)
	if err := json.Unmarshal(bytes, &m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *ConfigLoader) SetConfig(configName conf


][0] * arr_tech_matrix[hwMatrix][1]
    let strip = neopixel.create(arr_tech_pin[pin], pixelAnzahl, NeoPixelMode.RGB)
    neop_ges[snr] = strip
    strip.setBrightness(strip_helligkeit)
    strip.clear()
    strip.show()
    neo_strip_anzahl = Math.max(snr + 1, neo_strip_anzahl)

    //serial.writeLine(snr + ":snr len: "+neop_ranges.length+" "+neop_ranges[snr]+" "+arr_tech_matrix[hwMatrix][0]+"/"+arr_tech_matrix[hwMatrix][1]);

    let xstrip: neopixel.Strip[] =[]
    for (let z = 0; z < arr_tech_matrix[hwMatrix][1]; z++) {
        xstrip.push(neop_ges[snr].range(z * arr_tech_matrix[hwMatrix][0], arr_tech_matrix[hwMatrix][0]))
    }
    if (neop_ranges[snr]==undefined) {
        neop_ranges.push(xstrip)
    } else {
        neop_ranges[snr]=xstrip
    }

}

function set_punkt(snr:number=0,x: number, y:number, color: number) {
    const hwx = arr_neop_settings[snr].hwMatrix[0];
    const hwy = arr_neop_settings[snr].hwMatrix[1];

    //let px = (hwy-y-1)*hwy + ((y % 2) ? hwx-(x % hwx)-1:(x % hwx))
    let t= x
    if ((y % 2)!=(hwy % 2)) {
       t=(hwx - 1 - x)
    }
    let px = (hwy-1-y) * hwx + t
    //serial.writeValue("x", px)
    neop_ges[snr].setPixelColor(px, color);
    neop_ges[snr].show()
}

function get_bst_matrix(zch: string = "A",hwy:number) {
    let found = bst_reihe.indexOf(zch)
    if (found==-1) {
        found=0;
    }
    return arr_zeichen[found].slice(0,hwy)
}

function scrollen (zstrip: neopixel.Strip[],hy:number) {
    for (let strip = 0; strip < hy; strip++) {
        let sh = (strip % 2) ? -1:1
        zstrip[strip].shift(sh)
    }
}
function get_ystreifen(z_matrix:Array<number>,bit:number=0,x_add:number=0,color:number,zstrip:neopixel.Strip[],hx:number) {
    z_matrix.forEach(function (zahl, zeile) {
        if (zahl & Math.pow(2, bit)) {
            let b=bit+x_add
            let px=(zeile % 2) ? (hx-1-b):b
            zstrip[zeile].setPixelColor(px, color)
        }
    })

}
function frei_matrix(zch_str:string) {
    let ret="";
    let zch_len = zch_str.length
    if (zch_str.indexOf(";")>-1) {
        const arr_split = zch_str.split(";")
        if (arr_split.length>2) {
            arr_zeichen[80]=arr_split.map(wert => parseInt(wert));
            zch_bit_breite=arr_split.length
            ret=";"
        }
    };
    return ret
}

function showtext (snr:number,txt:string="A",color:number,scroll_flag:boolean=false) {

    const hwx = arr_neop_settings[snr].hwMatrix[0];
    cons


licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package udpip

import (
	"crypto/rand"
	"encoding/binary"
	"hash/fnv"
	"net/netip"
	"testing"
	"time"

	"github.com/gopacket/gopacket"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/scionproto/scion/pkg/addr"
	"github.com/scionproto/scion/pkg/private/serrors"
	"github.com/scionproto/scion/pkg/private/util"
	"github.com/scionproto/scion/pkg/scrypto"
	"github.com/scionproto/scion/pkg/slayers"
	"github.com/scionproto/scion/pkg/slayers/path"
	"github.com/scionproto/scion/pkg/slayers/path/scion"
)

var (
	testKey = []byte("testkey_xxxxxxxx")
)

func computeMAC(t *testing.T, key []byte, info path.InfoField, hf path.HopField) [path.MacLen]byte {
	mac, err := scrypto.InitMac(key)
	require.NoError(t, err)
	return path.MAC(mac, info, hf, nil)
}

// Prepares a message that is arriving at its last hop, incoming through interface 1.
func prepBaseMsg(t *testing.T, flowId uint32) *slayers.SCION {
	spkt := &slayers.SCION{
		Version:      0,
		TrafficClass: 0xb8,
		FlowID:       flowId,
		NextHdr:      slayers.L4UDP,
		PathType:     scion.PathType,
		DstIA:        addr.MustParseIA("1-ff00:0:110"),
		SrcIA:        addr.MustParseIA("1-ff00:0:111"),
		Path:         &scion.Raw{},
		PayloadLen:   18,
	}

	dpath := &scion.Decoded{
		Base: scion.Base{
			PathMeta: scion.MetaHdr{
				CurrHF: 2,
				SegLen: [3]uint8{3, 0, 0},
			},
			NumINF:  1,
			NumHops: 3,
		},
		InfoFields: []path.InfoField{
			{SegID: 0x111, ConsDir: true, Timestamp: util.TimeToSecs(time.Now())},
		},

		HopFields: []path.HopField{
			{ConsIngress: 41, ConsEgress: 40},
			{ConsIngress: 31, ConsEgress: 30},
			{ConsIngress: 1, ConsEgress: 0},
		},
	}
	dpath.HopFields[2].Mac = computeMAC(t, testKey, dpath.InfoFields[0], dpath.HopFields[2])
	spkt.Path = dpath
	return spkt
}

func TestComputeProcId(t *testing.T) {
	randomValueBytes := []byte{1, 2, 3, 4}
	numProcs := 10000

	// ComputeProcID expects the per-receiver random number to be pre-hashed into the seed that we
	// pass.
	hashSeed := fnv1aOffset32
	for _, c := range randomValueBytes {
		hashSeed = hashFNV1a(hashSeed, c)
	}

	// this function returns the procID as we expect it by using the  slayers.SCION serialization
	// implementation.
	referenceHash := func(s *slayers.SCION) uint32 {
		flowBuf := make([]byte, 4)
		binary.BigEndian.PutUint32(flowBuf, s.FlowID)
		flowBuf[0] &= 0xF
		tmpBuffer := make([]byte, 100)
		hasher := fnv.New32a()
		hasher.Write(randomValueBytes)
		hasher.Write(flowBuf[1:4])
		if err := s.SerializeAddrHdr(tmpBuffer); err != nil {
			panic(err)
		}
		hasher.Write(tmpBuffer[:s.AddrHdrLen()])
		return hasher.Sum32() % uint32(numProcs)
	}


 one"
            }
            2: {
                size: 128
                name: "Up two"
            }
        }
        down: {
            0: {
                size: 512
                mode: BlockIfFull
                name: "Down zero"
            }
        }
    };

    let mut output2 = channels.up.1;
    writeln!(
        output2,
        "Hi! I will turn anything you type on channel 0 into upper case."
    )
    .ok();

    let mut output = channels.up.0;
    let mut log = channels.up.2;
    let mut input = channels.down.0;
    let mut buf = [0u8; 512];
    if let Some(nrf52) = Board::take() {
        let mut timer = Timer::new(nrf52.TIMER0);
        let mut count: u8 = 0;
        loop {
            let bytes = input.read(&mut buf[..]);
            if bytes > 0 {
                for c in buf.iter_mut() {
                    c.make_ascii_uppercase();
                }

                let mut p = 0;
                while p < bytes {
                    p += output.write(&buf[p..bytes]);
                }
            }

            writeln!(log, "Messsge no. {}/{}", count, bytes).ok();

            if count >= u8::MAX {
                count = 0;
            } else {
                count += 1;
            }

            delay(&mut timer, 250_000);
        }
    };

    loop {
        continue;
    }
}

fn delay<T>(timer: &mut Timer<T>, cycles: u32)
where
    T: timer::Instance,
{
    timer.start(cycles);
    let _ = block!(timer.wait());
}
<gh_stars>0
use std::io;
use std::path::{Component, Path, PathBuf};

pub fn absolutize<P, Q>(relative_to: P, path: Q) -> PathBuf
where
    P: AsRef<Path>,
    Q: AsRef<Path>,
{
    let path = if path.as_ref() == Path::new(".") {
        // Joining a Path with '.' appends a '.' at the end, making the prompt
        // more ugly - so we don't do anything, which should result in an equal
        // path on all supported systems.
        relative_to.as_ref().to_owned()
    } else if path.as_ref().starts_with("~") {
        #[cfg(feature = "dirs")]
        {
            let expanded_path = expand_tilde(path.as_ref());
            match expanded_path {
                Some(p) => p,
                _ => path.as_ref().to_owned(),
            }
        }
        #[cfg(not(feature = "dirs"))]
        relative_to.as_ref().join(path)
    } else {
        relative_to.as_ref().join(path)
    };

    let (relative_to, path) = {
        let components: Vec<_> = path.components().collect();
        let separator = components
            .iter()
            .enumerate()
            .find(|(_, c)| c == &&Component::CurDir || c == &&Component::ParentDir);

        if let Some((index, _)) = separator {
            let (absolute, relative) = components.split_at(index);
            let absolute: PathBuf = absolute.iter().collect();
            let relative: PathBuf = relative.iter().collect();

            (absolute, relative)
        } else {
            (
                relative_to.as_ref().to_path_buf(),
                components.iter().collect::<PathBuf>(),
            )
        }
    };

    let path = if path.is_relative() {
        let mut result = relative_to;
        path.components().for_each(|component| match compo


_SUBLEVEL=$(awk '/^SUBLEVEL =/{print $NF}' $GOPATH/$LINUX_VER/Makefile)
$ export KERNEL_EXTRAVERSION=$(awk '/^EXTRAVERSION =/{print $NF}' $GOPATH/$LINUX_VER/Makefile)
$ export KERNEL_ROOTFS_DIR=${KERNEL_MAJOR_VERSION}.${KERNEL_PATHLEVEL}.${KERNEL_SUBLEVEL}${KERNEL_EXTRAVERSION}
$ cd $QAT_SRC
$ KERNEL_SOURCE_ROOT=$GOPATH/$LINUX_VER ./configure --disable-qat-lkcf --enable-icp-sriov=guest
$ sudo -E make all -j$(nproc)
$ sudo -E make INSTALL_MOD_PATH=$ROOTFS_DIR qat-driver-install -j$(nproc)
```
The `usdm_drv` module also needs to be copied into the rootfs modules path and
`depmod` should be run.
```sh
$ sudo cp $QAT_SRC/build/usdm_drv.ko $ROOTFS_DIR/usr/lib/modules/${KERNEL_ROOTFS_DIR}/updates/drivers
$ sudo depmod -a -b ${ROOTFS_DIR} ${KERNEL_ROOTFS_DIR}
$ cd ${OSBUILDER}/osbuilder/image-builder
$ script -fec 'sudo -E USE_DOCKER=true ./image_builder.sh ${ROOTFS_DIR}'
```

> **Note: Ignore any errors on modules.builtin and modules.order when running
> `depmod`.**

### Copy Kata rootfs

```sh
$ mkdir -p $KATA_ROOTFS_LOCATION
$ cp ${OSBUILDER}/osbuilder/image-builder/kata-containers.img $KATA_ROOTFS_LOCATION
```

### Update Kata configuration to point to custom kernel and rootfs

You must update the `configuration.toml` for Kata Containers to point to the
custom kernel, custom rootfs, and to specify which modules to load when the
virtual machine is booted when a container is run. The following example
assumes you installed an Intel QAT, and you need to load those modules.

```sh
$ sudo mkdir -p /etc/kata-containers
$ sudo cp /usr/share/defaults/kata-containers/configuration-qemu.toml /etc/kata-containers/configuration.toml
$ sudo sed -i "s|kernel_params = \"\"|kernel_params = \"modules-load=usdm_drv,qat_c62xvf\"|g" /etc/kata-containers/configuration.toml
$ sudo sed -i "s|\/usr\/share\/kata-containers\/kata-containers.img|${KATA_KERNEL_LOCATION}\/kata-containers.img|g" /etc/kata-containers/configuration.toml
$ sudo sed -i "s|\/usr\/share\/kata-containers\/vmlinuz.container|${KATA_ROOTFS_LOCATION}\/vmlinuz-${LINUX_VER}_qat|g" /etc/kata-containers/configuration.toml
```

## Verify Intel QAT works in a Docker Kata Containers container

The following instructions leverage an OpenSSL Dockerfile that builds the
Intel QAT engine to allow OpenSSL to offload crypto functions. It is a
convenient way to test that VFIO device passthrough for the Intel QAT VF’s are
working properly with the Kata Containers VM.

## Build OpenSSL Intel QAT engine container

Use the OpenSSL Intel QAT [Dockerfile](https://github.com/intel/intel-device-plugins-for-kubernetes/tree/master/demo/openssl-qat-engine)
to build a container image with an optimized OpenSSL engine for
Intel QAT. Using `docker build` with the Kata Containers runtime can sometimes
have issues. Therefore, we recommended you change the default runtime to
`runc` before doing a build. Instructions for this are below.

```sh
$ cd $QAT_SRC
$ curl -O $QAT_DOCKERFILE
$ sudo sed -


="webauthn-device-description-{{ forloop.counter }}" class="button button-small no">{% translate "Delete" context "verb, action" %}

                {% endfor %}

        {% else %}

{% trans "Authenticate with Passkeys" %}

                {% blocktrans trimmed %}
                Passkeys allow you to verify your identity using touch, facial recognition, a device password, or a PIN. They can be used for sign-in as a simple and secure alternative to your password and two-factor credentials.
                {% endblocktrans %}

                {% trans "Get started with Passkeys" %}

        {% endif %}

{% endblock %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <meta charset="UTF-8">
  <meta content="width=device-width, initial-scale=1" name="viewport">
  <meta name="x-apple-disable-message-reformatting">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta content="telephone=no" name="format-detection">
  <title>Are you trying to sign in?</title>


      assert.is_not_nil(err)
        assert.matches("query_command undefined for pluginserver gopher", err)
      end)
    end)
    describe("warns if", function()
      it("no start_command (meaning process is externally maintained)", function()
        local spy_log = spy.on(log, "warn")

        finally(function()
          log.warn:revert()
          assert:unregister("matcher", "str_match")
        end)

        assert:register("matcher", "str_match", function (_state, arguments)
          local expected = arguments[1]
          return function(value)
            return string.match(value, expected) ~= nil
          end
        end)

        local _, err = conf_loader(nil, {
          pluginserver_names = "gopher",
          pluginserver_gopher_query_cmd = "gopher -dump",
        })
        assert.is_nil(err)
        assert.spy(spy_log).was_called(1)
        assert.spy(spy_log).was_called_with("start_command undefined for pluginserver gopher; assuming external process management")
      end)
    end)
    it("fills in default settings", function()
      -- mock default conf loader path - as we cannot
      -- reliably write in the default path (/usr/local/bin)
      package.loaded["kong.conf_loader"] = nil
      local conf_constants = require"kong.conf_loader.constants"
      conf_constants.DEFAULT_PLUGINSERVER_PATH = helpers.external_plugins_path .. "/go"
      local conf_loader = require"kong.conf_loader"

      helpers.build_go_plugins(helpers.external_plugins_path .. "/go")

      finally(function()
        package.loaded["kong.conf_loader"] = nil
        package.loaded["kong.conf_loader.constants"] = nil
      end)

      local conf, err = conf_loader(nil, {
        pluginserver_names = "go-hello",
        -- leave out start_command and query_command so that the defaults
        -- are used
      })
      assert.is_nil(err)
      assert.same("go-hello", conf.pluginservers[1].name)
      assert.same("./spec/fixtures/external_plugins/go/go-hello -dump", conf.pluginservers[1].query_command)
      assert.same("./spec/fixtures/external_plugins/go/go-hello", conf.pluginservers[1].start_command)
      assert.same(conf.prefix .. "/go-hello.socket", conf.pluginservers[1].socket)
    end)
    it("accepts custom settings", function()
      local conf, err = conf_loader(nil, {
        pluginserver_names = "gopher",
        pluginserver_gopher_query_cmd = "gopher -dump",
        pluginserver_gopher_start_cmd = "gopher -p $KONG_PREFIX",
        pluginserver_gopher_socket = "/foo/bar/gopher.socket",
      })
      assert.is_nil(err)
      assert.same("gopher", conf.pluginservers[1].name)
      assert.same("gopher -dump", conf.pluginservers[1].query_command)
      assert.same("gopher -p $KONG_PREFIX", conf.pluginservers[1].start_command)
      assert.same("/foo/bar/gopher.socket", conf.pluginservers[1].socket)
    end)
  end)
end)


#),
            (r#"null"#),
            (r#"true"#),
            (r#"false"#),
        ];

        for json_str in legal_cases {
            let resp = Json::from_str(json_str);
            assert!(resp.is_ok());
        }

        let cases = vec![
            (
                r#"9223372036854776000"#,
                Json::from_f64(9223372036854776000.0),
            ),
            (
                r#"9223372036854775807"#,
                Json::from_i64(9223372036854775807),
            ),
        ];

        for (json_str, json) in cases {
            let resp = Json::from_str(json_str);
            assert!(resp.is_ok());
            assert_eq!(resp.unwrap(), json.unwrap());
        }

        let illegal_cases = vec!["[pxx,apaa]", "hpeheh", ""];
        for json_str in illegal_cases {
            let resp = Json::from_str(json_str);
            assert!(resp.is_err());
        }
    }
}
use super::{
    timer::{TimerIFace, TimerSpeed},
    HighSpeed, LowSpeed,
};
use crate::gpio::{OutputPin, OutputSignal};
use esp32::ledc::RegisterBlock;
use paste::paste;

/// Channel errors
#[derive(Debug)]
pub enum Error {
    /// Invalid duty % value
    Duty,
    /// Timer not configured
    Timer,
    /// Channel not configured
    Channel,
}

/// Channel number
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Number {
    Channel0,
    Channel1,
    Channel2,
    Channel3,
    Channel4,
    Channel5,
    Channel6,
    Channel7,
}

/// Channel configuration
pub mod config {
    use crate::ledc::timer::{TimerIFace, TimerSpeed};

    /// Channel configuration
    #[derive(Copy, Clone)]
    pub struct Config<'a, S: TimerSpeed> {
        pub timer: &'a dyn TimerIFace<S>,
        pub duty_pct: f32,
    }
}

/// Channel interface
pub trait ChannelIFace<
    'a,
    S: TimerSpeed + 'a,
    O: OutputPin = crate::gpio::Gpio1<crate::gpio::Output<crate::gpio::PushPull>>,
> where
    Channel<'a, S, O>: ChannelHW<O>,
{
    /// Configure channel
    fn configure(&mut self, config: config::Config<'a, S>) -> Result<(), Error>;

    /// Set channel duty HW
    fn set_duty(&self, duty_pct: f32) -> Result<(), Error>;
}

/// Channel HW interface
pub trait ChannelHW<O: OutputPin> {
    /// Configure Channel HW except for the duty which is set via [`Self::set_duty_hw`].
    fn configure_hw(&mut self) -> Result<(), Error>;

    /// Set channel duty HW
    fn set_duty_hw(&self, duty: u32);
}

/// Channel struct
pub struct Channel<'a, S: TimerSpeed, O: OutputPin> {
    ledc: &'a RegisterBlock,
    timer: Option<&'a dyn TimerIFace<S>>,
    number: Number,
    output_pin: O,
}

impl<'a, S: TimerSpeed, O: OutputPin> Channel<'a, S, O> {
    /// Return a new channel
    pub fn new(number: Number, output_pin: O) -> Self {
        let ledc = unsafe { &*esp32::LEDC::ptr() };
        Channel {
            ledc,
            timer: None,
            number,
            output_pin,
        }
    }
}

impl<'a, S: TimerSpeed, O: OutputPin> ChannelIFace<'a, S, O> for Channel<'a, S, O>
where
    Channel<'a, S, O>: ChannelHW<O>,
{
    /// Configure channel
    fn configure(&mut self, config:


st.EmptyResponse{})
		return
	}

	// Reset task status
	taskGroup.State = TaskGroupStateRunning
	s.db.Save(&taskGroup)
	for _, task := range tasks {
		task.Error = nil
		task.State = TaskStateRunning
		s.db.Save(task)
	}

	if !s.scheduler.AsyncStart(&taskGroup, tasks) {
		log.Error("Failed to retry task group", zap.Uint("task_group_id", taskGroup.ID))
	}
	c.JSON(http.StatusOK, rest.EmptyResponse{})
}

// @Summary Cancel running tasks in a log search task group
// @Param id path string true "task group id"
// @Security JwtAuth
// @Success 200 {object} rest.EmptyResponse
// @Failure 401 {object} rest.ErrorResponse
// @Failure 400 {object} rest.ErrorResponse
// @Router /logs/taskgroups/{id}/cancel [post]
func (s *Service) CancelTask(c *gin.Context) {
	taskGroupID, err := strconv.Atoi(c.Param("id"))
	if err != nil {
		rest.Error(c, rest.ErrBadRequest.NewWithNoMessage())
		return
	}
	taskGroup := TaskGroupModel{}
	err = s.db.First(&taskGroup, taskGroupID).Error
	if err != nil {
		rest.Error(c, err)
		return
	}
	if taskGroup.State != TaskGroupStateRunning {
		rest.Error(c, rest.ErrBadRequest.New("Task is not running"))
		return
	}
	s.scheduler.AsyncAbort(uint(taskGroupID))
	c.JSON(http.StatusOK, rest.EmptyResponse{})
}

// @Summary Delete a log search task group
// @Param id path string true "task group id"
// @Security JwtAuth
// @Success 200 {object} rest.EmptyResponse
// @Failure 401 {object} rest.ErrorResponse
// @Failure 500 {object} rest.ErrorResponse
// @Router /logs/taskgroups/{id} [delete]
func (s *Service) DeleteTaskGroup(c *gin.Context) {
	taskGroupID := c.Param("id")
	taskGroup := TaskGroupModel{}
	err := s.db.Where("id = ? AND state != ?", taskGroupID, TaskGroupStateRunning).First(&taskGroup).Error
	if err != nil {
		rest.Error(c, err)
		return
	}
	taskGroup.Delete(s.db)
	c.JSON(http.StatusOK, rest.EmptyResponse{})
}

// @Summary Generate a download token for downloading logs
// @Produce plain
// @Param id query []string false "task id" collectionFormat(csv)
// @Security JwtAuth
// @Success 200 {string} string "xxx"
// @Failure 400 {object} rest.ErrorResponse
// @Failure 401 {object} rest.ErrorResponse
// @Router /logs/download/acquire_token [get]
func (s *Service) GetDownloadToken(c *gin.Context) {
	ids := c.QueryArray("id")
	str := strings.Join(ids, ",")
	token, err := utils.NewJWTString("logs/download", str)
	if err != nil {
		rest.Error(c, err)
		return
	}
	c.String(http.StatusOK, token)
}

// @Summary Download logs
// @Produce application/x-tar,application/zip
// @Param token query string true "download token"
// @Failure 400 {object} rest.ErrorResponse
// @Failure 401 {object} rest.ErrorResponse
// @Failure 500 {object} rest.ErrorResponse
// @Router /logs/download [get]
func (s *Service) DownloadLogs(c *gin.Context) {
	token := c.Query("token")
	str, err := utils.ParseJWTString("logs/download", token)
	if err != nil {
		rest.Error(c, rest.ErrBadRequest.NewWithNoMessage())
		return


(nameof(fileProvider));

            FileProvider = fileProvider;
            _appendStreamBufferSize = appendStreamBufferSize;
            _appendStreamFileOptions = (appendStreamFileOptions & ~FileOptions.RandomAccess) | FileOptions.SequentialScan | FileOptions.Asynchronous;
            _isOwner = isOwner;
        }

        public void Dispose()
        {
            if (_isOwner)
                FileProvider.Dispose();
        }

        public PhysicalFileProvider FileProvider { get; }

        IFileProvider IFileAppender.FileProvider => FileProvider;

        public Task<bool> EnsureDirAsync(IFileInfo fileInfo, CancellationToken cancellationToken = default)
        {
            var dirPath = Path.GetDirectoryName(fileInfo.PhysicalPath);
            if (Directory.Exists(dirPath))
                return Task.FromResult(false);

            Directory.CreateDirectory(dirPath);
            return Task.FromResult(true);
        }

        public Stream CreateAppendStream(IFileInfo fileInfo)
        {
            return new FileStream(fileInfo.PhysicalPath, FileMode.Append, FileAccess.Write, FileShare.Read, _appendStreamBufferSize, _appendStreamFileOptions);
        }
    }
}


= N end

do
  local stretchdepth = maxdepth + 1
  local stretchtree = BottomUpTree(0, stretchdepth)
  print("stretch tree of depth", stretchdepth, "check: ", ItemCheck(stretchtree))
end

local longlivedtree = BottomUpTree(0, maxdepth)

for depth=mindepth,maxdepth,2 do
  local iterations = 2 ^ (maxdepth - depth + mindepth)
  local check = 0
  for i=1,iterations do
    check = check + ItemCheck(BottomUpTree(1, depth)) +
            ItemCheck(BottomUpTree(-1, depth))
  end
  print(iterations*2, "trees of depth", depth, "check: ", check)
end

print("long lived tree of depth", maxdepth, "check:", ItemCheck(longlivedtree))


les/one-var.html)

    > Tại sao? Khai báo theo cách này giúp dễ thêm các khai báo mới, và bạn chẳng phải nghĩ về việc phải dùng `;` hay `,`. Bạn còn có thể bước qua mỗi khai báo trong trình gỡ lỗi, thay vì nhảy qua toàn bộ chúng trong một bước.

    ``` javascript
    // không tốt
    const items = getItems(),
        goSportsTeam = true,
        dragonball = 'z';

    // không tốt
    // (so sánh với trên kia và thử tìm ra lỗi ở đây)
    const items = getItems(),
        goSportsTeam = true;
        dragonball = 'z';

    // tốt
    const items = getItems();
    const goSportsTeam = true;
    const dragonball = 'z';
    ```

  - [13.3](#variables--const-let-group) Nhóm tất cả các `const` và rồi nhóm tất cả các `let`.

    > Tại sao? Điều này hữu ích khi, sau đó, bạn sẽ cần gán lại một biến dựa trên các biến đã gán trước đó.

    ``` javascript
    // không tốt
    let i, len, dragonball,
        items = getItems(),
        goSportsTeam = true;

    // không tốt
    let i;
    const items = getItems();
    let dragonball;
    const goSportsTeam = true;
    let len;

    // tốt
    const goSportsTeam = true;
    const items = getItems();
    let dragonball;
    let i;
    let length;
    ```

  - [13.4](#variables--define-where-used) Chỉ gán biến khi cần, nhưng nhớ đặt chúng ở một nơi hợp lý.

    > Tại sao? `let` và `const` thuộc phạm vi khối, không phải phạm vi hàm.

    ``` javascript
    // không tốt - phép gọi hàm không cần thiết
    function checkName(hasName) {
      const name = getName();

      if (hasName === 'thí nghiệm') {
        return false;
      }

      if (name === 'thí nghiệm') {
        this.setName('');
        return false;
      }

      return name;
    }

    // tốt
    function checkName(hasName) {
      if (hasName === 'thí nghiệm') {
        return false;
      }

      const name = getName();

      if (name === 'thí nghiệm') {
        this.setName('');
        return false;
      }

      return name;
    }
    ```

  - [13.5](#variables--no-chain-assignment) Đừng nối chuỗi các phép gán. eslint: [`no-multi-assign`](https://eslint.org/docs/rules/no-multi-assign)

    > Tại sao? Việc nối chuỗi


orm-control:focus{color:#4f4f4f;background-color:#fff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 0 .25rem rgba(59,113,202,.25)}.form-control::-webkit-date-and-time-value{height:1.6em}.form-control::-moz-placeholder{color:#757575;opacity:1}.form-control::placeholder{color:#757575;opacity:1}.form-control:disabled{background-color:#eee;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#4f4f4f;background-color:#eee;pointer-events:none;border:0 solid;border-color:inherit;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#e2e2e2}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.6;color:#4f4f4f;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.6em + .5rem + 2px);padding:.25rem .5rem;font-size:.775rem;border-radius:.25rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.6em + 1rem + 2px);padding:.5rem 1rem;font-size:1rem;border-radius:.5rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.6em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.6em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.6em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.6em + .75rem + 2px);padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.25rem}.form-control-color::-webkit-color-swatch{border-radius:.25rem}.form-control-color.form-control-sm{height:calc(1.6em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.6em + 1rem + 2px)}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.6;color:#4f4f4f;background-color:#fff;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='


lse None,
                            f"+ {ibmi_json_path}" if ibmi_json_content else None,
                            f"+ {rules_mk_path}" if rules_mk_content else None,
                        ]))))
        if force or yes(input('Continue? (yes) ')):
            create_file(iproj_json_path, proj_spec.generate_iproj_json(), force)
            create_file(ibmi_json_path, proj_spec.generate_ibmi_json(), force)
            create_file(rules_mk_path, proj_spec.generate_rules_mk(), force)
        else:
            _init_cancelled()

if __name__ == "__main__":
    import doctest

    doctest.testmod()


// generated from <Windows SDK Path>\shared\d3d9.h
using System;
using System.Runtime.InteropServices;

namespace DirectN
{
    [ComImport, Guid("b18b10ce-2649-405a-870f-95f777d4313a"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public partial interface IDirect3DDevice9Ex : IDirect3DDevice9
    {
        // IDirect3DDevice9
        [PreserveSig]
        new HRESULT TestCooperativeLevel();

        [PreserveSig]
        new uint GetAvailableTextureMem();

        [PreserveSig]
        new HRESULT EvictManagedResources();

        [PreserveSig]
        new HRESULT GetDirect3D(out IDirect3D9 ppD3D9);

        [PreserveSig]
        new HRESULT GetDeviceCaps(ref _D3DCAPS9 pCaps);

        [PreserveSig]
        new HRESULT GetDisplayMode(uint iSwapChain, ref _D3DDISPLAYMODE pMode);

        [PreserveSig]
        new HRESULT GetCreationParameters(IntPtr pParameters);

        [PreserveSig]
        new HRESULT SetCursorProperties(uint XHotSpot, uint YHotSpot, IDirect3DSurface9 pCursorBitmap);

        [PreserveSig]
        new void SetCursorPosition(int X, int Y, uint Flags);

        [PreserveSig]
        new bool ShowCursor(bool bShow);

        [PreserveSig]
        new HRESULT CreateAdditionalSwapChain(IntPtr pPresentationParameters, out IDirect3DSwapChain9 pSwapChain);

        [PreserveSig]
        new HRESULT GetSwapChain(uint iSwapChain, out IDirect3DSwapChain9 pSwapChain);

        [PreserveSig]
        new uint GetNumberOfSwapChains();

        [PreserveSig]
        new HRESULT Reset(IntPtr pPresentationParameters);

        [PreserveSig]
        new HRESULT Present(ref tagRECT pSourceRect, ref tagRECT pDestRect, IntPtr hDestWindowOverride, ref _RGNDATA pDirtyRegion);

        [PreserveSig]
        new HRESULT GetBackBuffer(uint iSwapChain, uint iBackBuffer, _D3DBACKBUFFER_TYPE Type, out IDirect3DSurface9 ppBackBuffer);

        [PreserveSig]
        new HRESULT GetRasterStatus(uint iSwapChain, ref _D3DRASTER_STATUS pRasterStatus);

        [PreserveSig]
        new HRESULT SetDialogBoxMode(bool bEnableDialogs);

        [PreserveSig]
        new void SetGammaRamp(uint iSwapChain, uint Flags, ref _D3DGAMMARAMP pRamp);

        [PreserveSig]
        new void GetGammaRamp(uint iSwapChain, ref _D3DGAMMARAMP pRamp);

        [PreserveSig]
        new HRESULT CreateTexture(uint Width, uint Height, uint Levels, uint Usage, _D3DFORMAT Format, _D3DPOOL Pool, out IDirect3DTexture9 ppTexture, IntPtr pSharedHandle);

        [PreserveSig]
        new HRESULT CreateVolumeTexture(uint Width, uint Height, uint Depth, uint Levels, uint Usage, _D3DFORMAT Format, _D3DPOOL Pool, out IDirect3DVolumeTexture9 ppVolumeTexture, IntPtr pSharedHandle);

        [PreserveSig]
        new HRESULT CreateCubeTexture(uint EdgeLength, uint Levels, uint Usage, _D3DFORMAT Format, _D3DPOOL Pool, out IDirect3DCubeTexture9 ppCubeTexture, IntPtr pSharedHandle);

        [PreserveSig]
        new HRESULT CreateVertexBuffer(uint Length, uint Usage, uint FVF, _D3DPOOL Pool, out IDirect3DVertexBuffer9 ppVertexBuffer, IntPtr pSharedHandle);

        [PreserveSig]
        new HRESULT CreateIndexBuffer(uint Length, uint Usage, _D3DFORMAT Format,


30, 0x7E)
var escapeToGroundBytes = getEscapeToGroundBytes()

// See http://www.vt100.net/emu/vt500_parser.png for description of the complex
// byte ranges below

func getEscapeToGroundBytes() []byte {
	escapeToGroundBytes := getByteRange(0x30, 0x4F)
	escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x51, 0x57)...)
	escapeToGroundBytes = append(escapeToGroundBytes, 0x59)
	escapeToGroundBytes = append(escapeToGroundBytes, 0x5A)
	escapeToGroundBytes = append(escapeToGroundBytes, 0x5C)
	escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x60, 0x7E)...)
	return escapeToGroundBytes
}

func getExecuteBytes() []byte {
	executeBytes := getByteRange(0x00, 0x17)
	executeBytes = append(executeBytes, 0x19)
	executeBytes = append(executeBytes, getByteRange(0x1C, 0x1F)...)
	return executeBytes
}

func getToGroundBytes() []byte {
	groundBytes := []byte{0x18}
	groundBytes = append(groundBytes, 0x1A)
	groundBytes = append(groundBytes, getByteRange(0x80, 0x8F)...)
	groundBytes = append(groundBytes, getByteRange(0x91, 0x97)...)
	groundBytes = append(groundBytes, 0x99)
	groundBytes = append(groundBytes, 0x9A)
	groundBytes = append(groundBytes, 0x9C)
	return groundBytes
}

// Delete		     7F hex  Always and everywhere ignored
// C1 Control	  80-9F hex  32 additional control characters
// G1 Displayable A1-FE hex  94 additional displayable characters
// Special		  A0+FF hex  Same as SPACE and DELETE
// +build windows

package winterm

const (
	horizontal = iota
	vertical
)

func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {
	if h.originMode {
		sr := h.effectiveSr(info.Window)
		return SMALL_RECT{
			Top:    sr.top,
			Bottom: sr.bottom,
			Left:   0,
			Right:  info.Size.X - 1,
		}
	} else {
		return SMALL_RECT{
			Top:    info.Window.Top,
			Bottom: info.Window.Bottom,
			Left:   0,
			Right:  info.Size.X - 1,
		}
	}
}

// setCursorPosition sets the cursor to the specified position, bounded to the screen size
func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {
	position.X = ensureInRange(position.X, window.Left, window.Right)
	position.Y = ensureInRange(position.Y, window.Top, window.Bottom)
	err := SetConsoleCursorPosition(h.fd, position)
	if err != nil {
		return err
	}
	h.logf("Cursor position set: (%d, %d)", position.X, position.Y)
	return err
}

func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error {
	return h.moveCursor(vertical, param)
}

func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error {
	return h.moveCursor(horizontal, param)
}

func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
	info, err := GetConsoleScreenBufferInfo(h.fd)
	if err != nil {
		return err
	}

	position := info.CursorPosition
	switch moveMode {
	case horizontal:
		position.X += int16(param)
	case vertical:
		position.Y += int16(param)
	}

	if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
		return err
	}

	return nil
}

func (h *windowsAnsiEventHandler) moveCursorLine(param int) error {
	info, err := GetConsoleScreenBufferInfo(h.fd)
	if err != nil {


 >= this->mem_size)
      {
        //this->fatal("Trying to read outside memory range (addr: 0x%x, mem size: 0x%x)\n", this->current_addr, this->mem_size);
      }
      else
      {
        this->current_data = this->data[this->current_addr];
        this->trace_msg(this->trace, 2, "Read byte from memory (address: 0x%6.6x, value: 0x%2.2x)", this->current_addr, this->current_data);
        if (this->cross_pagesize_limit_mask)
        {
          this->current_addr = (this->current_addr & this->cross_pagesize_limit_mask) | ((this->current_addr + 1) & ~this->cross_pagesize_limit_mask);
        }
        else
        {
          this->current_addr++;
        }
      }
    }

    if (this->qpi || this->quad_command)
    {
      int bits = (this->current_data >> 4) & 0xf;
      this->current_data <<= 4;
      this->qspi0->set_qpi_data((bits >> 0) & 1, (bits >> 1) & 1, (bits >> 2) & 1, (bits >> 3) & 1, 0xf);
      this->cmd_count += 4;
    }
    else
    {
      int bit = (this->current_data >> 7) & 1;
      this->current_data <<= 1;
      this->qspi0->set_data(bit);
      this->cmd_count++;
    }

    if (this->cmd_count == 8)
    {
      this->cmd_count = 0;
    }
  }
}

void Spiram::sck_edge(int64_t timestamp, int sck, int sdio0, int sdio1, int sdio2, int sdio3, int mask)
{
  if (this->check_refresh(timestamp))
    return;

  this->trace_msg(this->trace, 4, "SCK edge (timestamp: %ld, sck: %d, data_0: %d, data_1: %d, data_2: %d, data_3: %d, mask: 0x%x)", timestamp, sck, sdio0, sdio1, sdio2, sdio3, mask);

  if (prev_sck == 1 && !sck)
  {
    handle_clk_low(timestamp, sdio0, sdio1, sdio2, sdio3, mask);
  }
  else if (prev_sck == 0 && sck)
  {
    handle_clk_high(timestamp, sdio0, sdio1, sdio2, sdio3, mask);
  }
  prev_sck = sck;
}

extern "C" Dpi_model *dpi_model_new(js::config *config, void *handle)
{
  return new Spiram(config, handle);
}
// dear imgui, v1.92.1
// (drawing and font code)

/*

Index of this file:

// [SECTION] STB libraries implementation
// [SECTION] Style functions
// [SECTION] ImDrawList
// [SECTION] ImTriangulator, ImDrawList concave polygon fill
// [SECTION] ImDrawListSplitter
// [SECTION] ImDrawData
// [SECTION] Helpers ShadeVertsXXX functions
// [SECTION] ImFontConfig
// [SECTION] ImFontAtlas, ImFontAtlasBuilder
// [SECTION] ImFontAtlas: backend for stb_truetype
// [SECTION] ImFontAtlas: glyph ranges helpers
// [SECTION] ImFontGlyphRangesBuilder
// [SECTION] ImFont
// [SECTION] ImGui Internal Render Helpers
// [SECTION] Decompression code
// [SECTION] Default font data (ProggyClean.ttf)

*/

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif

#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif

#include "imgui.h"
#ifndef IMGUI_DISABLE
#include "imgui_internal.h"
#ifdef IMGUI_ENABLE_FREETYPE
#include "misc/freetype/imgui_freetype.h"
#endif

#include <stdio.h>      // vsnprintf, sscanf, printf
#include <stdint.h>     // intptr_t

// Visual Studio warnings
#ifdef _MSC_VER
#pragma warning (disable: 4127)     // condition expression is constant
#pragma warning (disable: 4505)     // unreferenced local function has been removed (stb stuff)
#pragma warning (disable: 4996)     // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#pragma warn


_update_floating_button_pos)

        else:
            return super().add_widget(widget, index=index, canvas=canvas)

    def on_scroll_stop(self, instance, touch):
        if self.show_on_stop:
            Clock.schedule_once(self.show_toolbar, 1)
        elif self.auto_adjust:
            Clock.schedule_once(self._auto_adjust, 1)

    def _auto_adjust(self, *args):
        middle_pos = self.height - self._toolbar.height / 2
        if self._toolbar.y < middle_pos:
            self.show_toolbar(animate=True)
        else:
            self.hide_toolbar(animate=True)

    def _update_floating_button_pos(self, *args):
        width = Window.width

        padding_y = self.float_button_padding_y

        if self.float_button_pos == "br":
            self._floating_button.x = width + 20
            self._floating_button.y = padding_y

        elif self.float_button_pos == "bl":
            raise NotImplementedError

        elif self.float_button_pos == "tr":
            raise NotImplementedError

        elif self.float_button_pos == "tl":
            raise NotImplementedError

    def _allow_float_anim(self, *args):
        self._float_anim_playing = False

    def show_float_button(self):
        if self._float_anim_playing:
            self._float_anim_playing = True
            return

        self._float_button_status = "open"
        Animation.stop_all(self._floating_button)
        width = Window.width
        anim = Animation(
            right=width - self.float_button_padding_x,
            d=self.duration,
            t=self.transition,
        )
        anim.bind(on_complete=self._allow_float_anim)
        anim.start(self._floating_button)

    def hide_float_button(self):
        if self._float_anim_playing:
            self._float_anim_playing = True
            return

        self._float_button_status = "close"
        Animation.stop_all(self._floating_button)
        width = Window.width
        width = Window.width
        anim = Animation(x=width + 20, d=self.duration, t=self.transition)
        anim.bind(on_complete=self._allow_float_anim)
        anim.start(self._floating_button)

    def get_float_button_status(self):
        return self._float_button_status

    def scroll_to(self, value):
        Animation(scroll_y=value, d=self.duration, t=self.transition).start(
            self.ids.scroll
        )


>(), 10);
        // Make sure that we can reference a pointer's limit
        let p = DescriptorTablePointer {
            limit: 5,
            base: VirtAddr::zero(),
        };
        let _: &u16 = &p.limit;
    }
}
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
    crate::events::types::InspectData,
    anyhow::{format_err, Error},
    fidl::endpoints::{DiscoverableService, Proxy},
    fidl_fuchsia_inspect::TreeMarker,
    fidl_fuchsia_inspect_deprecated::InspectMarker,
    fidl_fuchsia_io::{DirectoryProxy, NodeInfo},
    files_async,
    futures::future::BoxFuture,
    futures::stream::StreamExt,
    futures::{FutureExt, TryFutureExt},
    io_util,
    log::error,
    parking_lot::Mutex,
    pin_utils::pin_mut,
    std::collections::HashMap,
    std::path::{Path, PathBuf},
    std::sync::Arc,
};

/// Mapping from a diagnostics filename to the underlying encoding of that
/// diagnostics data.
pub type DataMap = HashMap<String, InspectData>;

pub type Moniker = String;

/// InspectDataCollector holds the information needed to retrieve the Inspect
/// VMOs associated with a particular component
#[derive(Clone, Debug)]
pub struct InspectDataCollector {
    /// The inspect data associated with a particular event.
    ///
    /// This is wrapped in an Arc Mutex so it can be shared between multiple data sources.
    ///
    /// Note: The Arc is needed so that we can both add the data map to a data collector
    ///       and trigger async collection of the data in the same method. This can only
    ///       be done by allowing the async method to populate the same data that is being
    ///       passed into the component event.
    inspect_data_map: Arc<Mutex<Option<DataMap>>>,
}

impl InspectDataCollector {
    /// Construct a new InspectDataCollector, wrapped by an Arc<Mutex>.
    pub fn new() -> Self {
        InspectDataCollector { inspect_data_map: Arc::new(Mutex::new(Some(DataMap::new()))) }
    }

    /// Convert a fully-qualified path to a directory-proxy in the executing namespace.
    /// NOTE: Currently does a synchronous directory-open, since there are no available
    ///       async apis.
    pub async fn find_directory_proxy(path: &Path) -> Result<DirectoryProxy, Error> {
        // TODO(fxbug.dev/36762): When available, use the async directory-open api.
        return io_util::open_directory_in_namespace(
            &path.to_string_lossy(),
            io_util::OPEN_RIGHT_READABLE | io_util::OPEN_RIGHT_WRITABLE,
        );
    }

    /// Searches the directory specified by inspect_directory_proxy for
    /// .inspect files and populates the `inspect_data_map` with the found VMOs.
    pub async fn populate_data_map(&mut self, inspect_proxy: &DirectoryProxy) -> Result<(), Error> {
        // TODO(fxbug.dev/36762): Use a streaming and bounded readdir API when available to avoid
        // being hung.
        let entries = files_async::readdir_recursive(inspect_proxy, /* timeout= */ None)
            .filter_map(|result| {
                async move {
                    // TODO(fxbug.dev/49157): decide how to show directories that we failed to read.
                    result.ok()
                }
            });
        pin_mut!(entries);
        // TODO(fxbug.dev/60250) convert this async loop to a stream so we can carry backpressure
        while let Some(entry) = entries.next().await {
            // We are only currently interested in inspect VMO files (root.inspect) and
            // inspect services.
            if let


\n  textarea&,\n  select[multiple]& {\n    height: auto;\n  }\n}\n',"modals.less":'//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n  overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal;\n  -webkit-overflow-scrolling: touch;\n\n  // Prevent Chrome on Windows from adding a focus outline. For details, see\n  // https://github.com/twbs/bootstrap/pull/10951.\n  outline: 0;\n\n  // When fading in the modal, animate it to slide down\n  &.fade .modal-dialog {\n    .translate(0, -25%);\n    .transition-transform(~"0.3s ease-out");\n  }\n  &.in .modal-dialog { .translate(0, 0)}\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  background-color: @modal-content-bg;\n  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n  border: 1px solid @modal-content-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 3px 9px rgba(0,0,0,.5));\n  background-clip: padding-box;\n  // Remove focus outline from opened modal\n  outline: none;\n}\n\n// Modal background\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal-background;\n  background-color: @modal-backdrop-bg;\n  // Fade for backdrop\n  &.fade { .opacity(0); }\n  &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  padding: @modal-title-padding;\n  border-bottom: 1px solid @modal-header-border-color;\n  min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n  margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n  margin: 0;\n  line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  margin-top: 15px;\n  padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;\n  text-align: right; // right align buttons\n  border-top: 1px solid @modal-footer-border-color;\n  &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n  // Properly space out buttons\n  .btn + .btn {\n    margin-left: 5px;\n    margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs\n  }\n  // but override that for button groups\n  .btn-


Util.getBool("dark", defValue: false);
    var contentPadding = ReadSetting.getPageDis().toDouble();
    Canvas pageCanvas = new Canvas(
        pageRecorder, Rect.fromLTWH(0, 0, Screen.width, Screen.height));
    Paint selfPaint = Paint()
      ..style = PaintingStyle.fill
      ..isAntiAlias = true
      ..strokeCap = StrokeCap.butt
      ..strokeWidth = 30.0;
    pageCanvas.drawImage(bgUI, Offset(0, 0), selfPaint);

    //章节
    textPainter.text = TextSpan(
        text: "${readPage.chapterName}",
        style: TextStyle(
          fontSize: 12 / Screen.textScaleFactor,
          color: isDark ? darkFont : Colors.black54,
          fontFamily: SpUtil.getString("fontName", defValue: "Roboto"),
        ));
    textPainter.layout();
    //章节高30 画在中间
    textPainter.paint(pageCanvas,
        Offset(contentPadding, 15 + SpUtil.getDouble(Common.top_safe_height)));
    //正文
    TextStyle style = TextStyle(
        color: SpUtil.getBool('dark') ? darkFont : Colors.black,
        locale: Locale('zh_CN'),
        fontFamily: SpUtil.getString("fontName", defValue: "Roboto"),
        fontSize: ReadSetting.getFontSize(),
        // letterSpacing: ReadSetting.getLatterSpace(),
        height: ReadSetting.getLineHeight());

    final TextPage page = readPage.pages[i];
    final lineCount = page.lines.length;
    for (var i = 0; i < lineCount; i++) {
      final line = page.lines[i];
      if (line.letterSpacing != null &&
          (line.letterSpacing < -0.1 || line.letterSpacing > 0.1)) {
        textPainter.text = TextSpan(
          text: line.text,
          style: style.copyWith(letterSpacing: line?.letterSpacing),
        );
      } else {
        textPainter.text = TextSpan(text: line.text, style: style);
      }
      final offset = Offset(
          line.dx, line.dy + 45 + SpUtil.getDouble(Common.top_safe_height));
      textPainter.layout();
      textPainter.paint(pageCanvas, offset);
    }
    //画电池
    double batteryPaddingLeft = contentPadding - 5;
    double mStrokeWidth = 1.0;
    double mPaintStrokeWidth = 1.5;
    Paint mPaint = Paint()..strokeWidth = mPaintStrokeWidth;
    var bottomH = Screen.height - 25 - Screen.bottomSafeHeight;
    var bottomTextH = bottomH - 2;
    //电池头部位置
    Size size = Size(22, 10);
    double batteryHeadLeft = 0;
    double batteryHeadTop = size.height / 4 + bottomH;
    double batteryHeadRight = size.width / 15;
    double batteryHeadBottom = batteryHeadTop + (size.height / 2);

    //电池框位置
    double batteryLeft = batteryHeadRight + mStrokeWidth;
    double batteryTop = bottomH;
    double batteryRight = size.width;
    double batteryBottom = size.height + bottomH;

    //电量位置
    double electricQuantityTotalWidth =
        size.width - batteryHeadRight - 5 * mStrokeWidth; //电池减去边框减去头部剩下的宽度
    double electricQuantityLeft = batteryHeadRight +
        2 * mStrokeWidth +
        electricQuantityTotalWidth * (1 - electricQuantity);
    double electricQuantityTop = mStrokeWidth * 2 + bottomH;
    double electricQuantityRight = size.width - 2 * mStrokeWidth;
    double electricQuantityBottom = size.height - 2 * mStrokeWidth + bottomH;

    mPaint.style = PaintingStyle.fill;
    mPaint.color = isDark ? darkFont : Color


er be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
    public class TextBoxControlBuilder : MobileControlBuilder
    {
        // Textbox allows whitespace inside text.

        /// <include file='doc\TextBox.uex' path='docs/doc[@for="TextBoxControlBuilder.AllowWhitespaceLiterals"]/*' />
        public override bool AllowWhitespaceLiterals()
        {
            return true;
        }
    }

}


float],$0x0 [d-float]
   63af3:	00          	halt
   63af4:	2c 00 00 00 	movc5 $0x0,$0x0,$0x0,$0x4,$0x0
   63af8:	04 00
   63afa:	00          	halt
   63afb:	00          	halt
   63afc:	1a 00       	bgtru 63afe <op+0x4ca2>
   63afe:	00          	halt
   63aff:	00          	halt
   63b00:	19 00       	blss 63b02 <op+0x4ca6>
   63b02:	00          	halt
   63b03:	00          	halt
   63b04:	18 00       	bgeq 63b06 <op+0x4caa>
   63b06:	00          	halt
   63b07:	00          	halt
   63b08:	fc          	xfc
   63b09:	ff ff       	.word 0xffff
   63b0b:	ff 6f       	.word 0xff6f
   63b0d:	00          	halt
   63b0e:	00          	halt
   63b0f:	00          	halt
   63b10:	6e 00 00    	cvtld $0x0,$0x0 [d-float]
   63b13:	00          	halt
   63b14:	6d 00 00    	cvtwd $0x0,$0x0 [d-float]
   63b17:	00          	halt
   63b18:	0c 00 00 00 	prober $0x0,$0x0,$0x0
   63b1c:	6f 00 00 00 	acbd $0x0 [d-float],$0x0 [d-float],$0x0 [d-float],63b90 <op+0x4d34>
   63b20:	6e 00
   63b22:	00          	halt
   63b23:	00          	halt
   63b24:	27 00 00 00 	divp $0x0,$0x0,$0x0,$0xc,$0x0,$0x0
   63b28:	0c 00 00
   63b2b:	00          	halt
   63b2c:	6e 00 00    	cvtld $0x0,$0x0 [d-float]
   63b2f:	00          	halt
   63b30:	6e 00 00    	cvtld $0x0,$0x0 [d-float]
   63b33:	00          	halt
   63b34:	6e 00 00    	cvtld $0x0,$0x0 [d-float]
   63b37:	00          	halt
   63b38:	7c 00       	clrd $0x0 [d-float]
   63b3a:	00          	halt
   63b3b:	00          	halt
   63b3c:	6f 00 00 00 	acbd $0x0 [d-float],$0x0 [d-float],$0x0 [d-float],63bb0 <op+0x4d54>
   63b40:	6e 00
   63b42:	00          	halt
   63b43:	00          	halt
   63b44:	27 00 00 00 	divp $0x0,$0x0,$0x0,-(r8),$0x0,$0x0
   63b48:	78 00 00
   63b4b:	00          	halt
   63b4c:	6f 00 00 00 	acbd $0x0 [d-float],$0x0 [d-float],$0x0 [d-float],63bc0 <op+0x4d64>
   63b50:	6e 00
   63b52:	00          	halt
   63b53:	00          	halt
   63b54:	17 00       	jmp $0x0
   63b56:	00          	halt
   63b57:	00          	halt
   63b58:	10


8월 15일 24시까지입니다!

완주 방법이 궁금하세요? 그렇다면 우리 HackaLearn 깃헙 리포지토리 에 방문하셔서 좀 더 자세히 알아보세요!

여러분의 완주를 기원합니다.

HackaLearn Korea 운영진 일동

                          <table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-


--'comment'"
	variablecomment = "lol you have to stop trying to deobfuscate",
	cryptvarcomment = true, -- encrypt variablecomment with bytecode
	variablename = "CRYPTED", -- "local 'variablename' = 'variablecomment' or something"
}

local com_ = "// Obfuscated By obfuscator"
if com_ == "" then
	com_ = _settings.comment
end

local varcom_ = "This Script Were Protected Stop De obfuscating The Script"
if varcom_ == "" then
	varcom_ = _settings.variablecomment
end
--io.write("Variable Name [CRYPTED]> ")
local varnam_ = "CrazyObfuscator"
if varnam_ == "" then
	varnam_ = _settings.variablecomment
end
--io.write("Crypt Var Value [y]/n> ")
local cryvar_ = "y"
local cryyes = true
if cryvar_:lower() == "n" then
	cryyes = false
else
	cryyes = true
end
local options_ = {
	comment = com_, -- "--'comment'"
	variablecomment = varcom_,
	cryptvarcomment = cryyes, -- encrypt variablecomment with bytecode
	variablename = varnam_, -- "local 'variablename' = 'variablecomment' or something"
}
--io.write("Press Enter to continue or ^C to cancel...")io.read()

local memoryleakerlolwhat = M_(Script,options_)

wfile:write(memoryleakerlolwhat)
wfile:close()
print(memoryleakerlolwhat)
--io.write("Done! Press Enter to exit...")io.read()


using Ciribob.DCS.SimpleRadio.Standalone.Common.Audio.LameWrapper;
using Ciribob.DCS.SimpleRadio.Standalone.Common.NetCoreServer;
using NAudio.Wave;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;

namespace Ciribob.DCS.SimpleRadio.Standalone.Common.Audio.NAudioLame;
#pragma warning disable IDE1006 // Naming Styles

/// Delegate for receiving output messages
/// <param name="text">Text to output</param>
/// <remarks>
///     Output from the LAME library is very limited.  At this stage only a few direct calls will result in output. No
///     output is normally generated during encoding.
/// </remarks>
public delegate void OutputHandler(string text);

/// Delegate for progress feedback from encoder
/// <param name="writer"><see cref="LameMP3FileWriter" /> instance that the progress update is for</param>
/// <param name="inputBytes">Total number of bytes passed to encoder</param>
/// <param name="outputBytes">Total number of bytes written to output</param>
/// <param name="finished">True if encoding process is completed</param>
public delegate void ProgressHandler(object writer, long inputBytes, long outputBytes, bool finished);

public class LameMP3FileWriter : Stream
{
    #region Progress

    /// Call any registered OnProgress handlers
    /// <param name="finished">True if called at end of output</param>
    protected void RaiseProgress(bool finished)
    {
        var timeDelta = DateTime.Now - _lastProgress;
        if (finished || timeDelta.TotalMilliseconds >= _minProgressTime)
        {
            _lastProgress = DateTime.Now;
            OnProgress?.Invoke(this, _inputByteCount, _outputByteCount, finished);
        }
    }

    #endregion

    #region Supporting classes

    /// Union class for fast buffer conversion
    /// <remarks>
    ///     <para>
    ///         Because of the way arrays work in .NET, all of the arrays will have the same
    ///         length value.  To prevent unaware code from trying to read/write from out of
    ///         bounds, allocation is done at the grain of the Least Common Multiple of the
    ///         sizes of the contained types.  In this case the LCM is 8 bytes - the size of
    ///         a double or a long - which simplifies allocation.
    ///     </para>
    ///     <para>
    ///         This means that when you ask for an array of 500 bytes you will actually get
    ///         an array of 504 bytes total - 63 doubles.  Any code that uses the length of
    ///         the array will see only 63 bytes, shorts, etc.
    ///     </para>
    ///     <para>
    ///         CodeAnalysis does not like this class, with good reason.  It should never be
    ///         exposed beyond the scope of the MP3FileWriter.
    ///     </para>
    /// </remarks>
    // uncomment to suppress CodeAnalysis warnings for the ArrayUnion class:
    [StructLayout(LayoutKind.Explicit)]
    private class ArrayUnion
    {
        /// Length of the byte array
        [FieldOffset(0)] public readonly int nBytes;

        /// Array of unsigned 8-bit integer values, length will be misreported
        [FieldOffset(16)] public readonly byte[] bytes;

        /// Array of signed 16-bit integer values, length will be misreported
        [FieldOffset(16)] public readonly short[] shorts;

        /// Array of signed 32-bit integer values, length will be misreported
        [FieldOffset(16)] public readonly int[] ints;

        /// Array of signed 64-bit integer values, length will be correct
        [FieldOffset(16)] public readonly long[] longs;

        /// Array of signed 32-bit floating point values, length w


originalText = saveButton.innerText;
      saveButton.disabled = true;
      saveButton.innerText = 'Saving...';
    }

    // Prepare the request data
    const requestData = {
      jobId: jobID,
      documentType: 'resume',
      content: JSON.stringify(resumeData)
    };

    // Get CSRF token
    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';

    // Send the save request
    fetch('/documents/save', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': csrfToken
      },
      body: JSON.stringify(requestData)
    })
    .then(response => {
      if (!response.ok) {
        throw new Error('Failed to save document');
      }
      return response.json();
    })
    .then(data => {
      if (!isFromDownload && typeof window.showNotification === 'function') {
        window.showNotification('Document saved successfully!', 'success', 'Save Complete');
      }
      resolve(data);
    })
    .catch(error => {
      console.error('Error saving resume:', error);
      if (!isFromDownload && typeof window.showNotification === 'function') {
        window.showNotification('Failed to save document. Please try again.', 'error', 'Save Failed');
      }
      reject(error);
    })
    .finally(() => {
      // Restore button state
      if (saveButton) {
        saveButton.disabled = false;
        saveButton.innerText = originalText;
      }
    });
  });
}

// This function is no longer needed as we use window.showNotification
// which is defined in base.html and properly handles toast notifications
})();
</script>

<!-- Generated by pkgdown: do not edit by hand -->
<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Aggregate (sum) values over all locations, and cumulatively over time. — aggregate_per_stream • scanstatistics</title>

<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha384-nrOSfDHtoPMzJHjVTdCopGqIqeYETSXhZDFyniQ8ZHcVy08QesyHcnOUpMpqnmWq" crossorigin="anonymous"></script>
<!-- Bootstrap -->

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<!-- Font Awesome icons -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">

<!-- pkgdown -->
<link href="../pkgdown.css" rel="stylesheet">
<script src="../jquery.sticky-kit.min.js"></script>
<script src="../pkgdown.js"></script>

<!-- mathjax -->
<script src='https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'></script>

<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5


ClippingPropertiesRef creates a new wrapper struct with underlying reference set to the original C object.
// Returns nil if the provided pointer to C object is nil too.
func NewPhysicalDevicePointClippingPropertiesRef(ref unsafe.Pointer) *PhysicalDevicePointClippingProperties {
	if ref == nil {
		return nil
	}
	obj := new(PhysicalDevicePointClippingProperties)
	obj.ref5afbd22f = (*C.VkPhysicalDevicePointClippingProperties)(unsafe.Pointer(ref))
	return obj
}

// PassRef returns the underlying C object, otherwise it will allocate one and set its values
// from this wrapping struct, counting allocations into an allocation map.
func (x *PhysicalDevicePointClippingProperties) PassRef() (*C.VkPhysicalDevicePointClippingProperties, *cgoAllocMap) {
	if x == nil {
		return nil, nil
	} else if x.ref5afbd22f != nil {
		return x.ref5afbd22f, nil
	}
	mem5afbd22f := allocPhysicalDevicePointClippingPropertiesMemory(1)
	ref5afbd22f := (*C.VkPhysicalDevicePointClippingProperties)(mem5afbd22f)
	allocs5afbd22f := new(cgoAllocMap)
	allocs5afbd22f.Add(mem5afbd22f)

	var csType_allocs *cgoAllocMap
	ref5afbd22f.sType, csType_allocs = (C.VkStructureType)(x.SType), cgoAllocsUnknown
	allocs5afbd22f.Borrow(csType_allocs)

	var cpNext_allocs *cgoAllocMap
	ref5afbd22f.pNext, cpNext_allocs = *(*unsafe.Pointer)(unsafe.Pointer(&x.PNext)), cgoAllocsUnknown
	allocs5afbd22f.Borrow(cpNext_allocs)

	var cpointClippingBehavior_allocs *cgoAllocMap
	ref5afbd22f.pointClippingBehavior, cpointClippingBehavior_allocs = (C.VkPointClippingBehavior)(x.PointClippingBehavior), cgoAllocsUnknown
	allocs5afbd22f.Borrow(cpointClippingBehavior_allocs)

	x.ref5afbd22f = ref5afbd22f
	x.allocs5afbd22f = allocs5afbd22f
	return ref5afbd22f, allocs5afbd22f

}

// PassValue does the same as PassRef except that it will try to dereference the returned pointer.
func (x PhysicalDevicePointClippingProperties) PassValue() (C.VkPhysicalDevicePointClippingProperties, *cgoAllocMap) {
	if x.ref5afbd22f != nil {
		return *x.ref5afbd22f, nil
	}
	ref, allocs := x.PassRef()
	return *ref, allocs
}

// Deref uses the underlying reference to C object and fills the wrapping struct with values.
// Do not forget to call this method whether you get a struct for C object and want to read its values.
func (x *PhysicalDevicePointClippingProperties) Deref() {
	if x.ref5afbd22f == nil {
		return
	}
	x.SType = (StructureType)(x.ref5afbd22f.sType)
	x.PNext = (unsafe.Pointer)(unsafe.Pointer(x.ref5afbd22f.pNext))
	x.PointClippingBehavior = (PointClippingBehavior)(x.ref5afbd22f.pointClippingBehavior)
}

// allocInputAttachmentAspectReferenceMemory allocates memory for type C.VkInputAttachmentAspectReference in C.
// The caller is responsible for freeing the this memory via C.free.
func allocInputAttachmentAspectReferenceMemory(n int) unsafe.Pointer {
	mem, err := C.calloc(C.size_t(n), (C.size_t)(sizeOfInputAttachment


Debug = findViewById(R.id.tvDebug)

        /** 用来显示当前坐姿状态 */
        ivStatus = findViewById(R.id.ivStatus)

        tvFPS = findViewById(R.id.tvFps)
        spnDevice = findViewById(R.id.spnDevice)
        spnCamera = findViewById(R.id.spnCamera)
        surfaceView = findViewById(R.id.surfaceView)
        initSpinner()
        if (!isCameraPermissionGranted()) {
            requestPermission()
        }
    }

    override fun onStart() {
        super.onStart()
        openCamera()
    }

    override fun onResume() {
        cameraSource?.resume()
        super.onResume()
    }

    override fun onPause() {
        cameraSource?.close()
        cameraSource = null
        super.onPause()
    }

    /** 检查相机权限是否有授权 */
    private fun isCameraPermissionGranted(): Boolean {
        return checkPermission(
            Manifest.permission.CAMERA,
            Process.myPid(),
            Process.myUid()
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun openCamera() {
        /** 音频播放 */
        val crosslegPlayer = MediaPlayer.create(this, R.raw.crossleg)
        val forwardheadPlayer = MediaPlayer.create(this, R.raw.forwardhead)
        val standardPlayer = MediaPlayer.create(this, R.raw.standard)
        var crosslegPlayerFlag = true
        var forwardheadPlayerFlag = true
        var standardPlayerFlag = true

        if (isCameraPermissionGranted()) {
            if (cameraSource == null) {
                cameraSource =
                    CameraSource(surfaceView, selectedCamera, object : CameraSource.CameraSourceListener {
                        override fun onFPSListener(fps: Int) {

                            /** 解释一下，tfe_pe_tv 的意思：tensorflow example、pose estimation、text view */
                            tvFPS.text = getString(R.string.tfe_pe_tv_fps, fps)
                        }

                        /** 对检测结果进行处理 */
                        override fun onDetectedInfo(
                            personScore: Float?,
                            poseLabels: List<Pair<String, Float>>?
                        ) {
                            tvScore.text = getString(R.string.tfe_pe_tv_score, personScore ?: 0f)

                            /** 分析目标姿态，给出提示 */
                            if (poseLabels != null && personScore != null && personScore > 0.3) {
                                missingCounter = 0
                                val sortedLabels = poseLabels.sortedByDescending { it.second }
                                when (sortedLabels[0].first) {
                                    "forwardhead" -> {
                                        crosslegCounter = 0
                                        standardCounter = 0
                                        if (poseRegister == "forwardhead") {
                                            forwardheadCounter++
                                        }
                                        poseRegister = "forwardhead"

                                        /** 显示当前坐姿状态：脖子前伸 */
                                        if (forwardheadCounter > 60) {

                                            /** 播放提示音 */
                                            if (forwardheadPlayerFlag) {
                                                forwardheadPlayer.start()
                                            }
                                            standardPlayerFlag = true
                                            crosslegPlayerFlag = true
                                            forwardheadPlayerFlag = false

                                            ivStatus.setImageResource(R.drawable.forwardhead_confirm)
                                        } else if (forwardheadCounter > 30) {
                                            ivStatus.setImageResource(R.drawable.forwardhead_suspect)
                                        }

                                        /** 显示 Debug 信息 */
                                        tvDebug.text = getString(R.string.tfe_pe_tv_debug, "${sortedLabels[0].first} $forwardheadCounter")
                                    }
                                    "crossleg" -> {
                                        forwardheadCounter = 0
                                        standardCounter = 0
                                        if (poseRegister == "crossleg") {
                                            crosslegCounter++
                                        }
                                        poseRegister = "crossleg"


local internalNpcName = "Tomruk The Ruddy"
local npcType = Game.createNpcType(internalNpcName)
local npcConfig = {}

npcConfig.name = internalNpcName
npcConfig.description = internalNpcName

npcConfig.health = 100
npcConfig.maxHealth = npcConfig.health
npcConfig.walkInterval = 2000
npcConfig.walkRadius = 2

npcConfig.outfit = {
	lookType = 553,
}

npcConfig.flags = {
	floorchange = false,
}

npcConfig.voices = {
	interval = 15000,
	chance = 50,
	{ text = "Interesting reaction. Bloodcurdling. Must inspect further." },
	{ text = "This is really sanguine!" },
	{ text = "Hmm... the conductors are too dry to transmit energy." },
	{ text = "Ah, fresh blood. My favourite." },
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)

npcType.onThink = function(npc, interval)
	npcHandler:onThink(npc, interval)
end

npcType.onAppear = function(npc, creature)
	npcHandler:onAppear(npc, creature)
end

npcType.onDisappear = function(npc, creature)
	npcHandler:onDisappear(npc, creature)
end

npcType.onMove = function(npc, creature, fromPosition, toPosition)
	npcHandler:onMove(npc, creature, fromPosition, toPosition)
end

npcType.onSay = function(npc, creature, type, message)
	npcHandler:onSay(npc, creature, type, message)
end

npcType.onCloseChannel = function(npc, creature)
	npcHandler:onCloseChannel(npc, creature)
end

local function creatureSayCallback(npc, creature, type, message)
	local player = Player(creature)
	local playerId = player:getId()

	if not npcHandler:checkInteraction(npc, creature) then
		return false
	end

	if (MsgContains(message, "scroll") or MsgContains(message, "mission")) and player:getStorageValue(Storage.Quest.U10_10.TheGravediggerOfDrefia.Mission35) == 1 and player:getStorageValue(Storage.Quest.U10_10.TheGravediggerOfDrefia.Mission36) < 1 then
		npcHandler:say({
			"So someone sent you after a scroll, eh? A stroll for a scroll! <chuckles> Sounds like an old-fashioned necromancer thing. ...",
			"Well, this piece here is a rather fascinating thing - see those strange blood stains? - ...",
			"My predecessors have had it for quite a while without finding out more - I was hoping to investigate, but there's always so much to do! ...",
			"Ah, so you want it, too? Well, do me a favour: fetch two samples and assist in my experiment, in exchange for the scroll piece. Yes?",
		}, npc, creature)
		npcHandler:setTopic(playerId, 1)
	elseif MsgContains(message, "yes") and npcHandler:getTopic(playerId) == 1 and player:getStorageValue(Storage.Quest.U10_10.TheGravediggerOfDrefia.Mission35) == 1 then
		npcHandler:say({
			"Sanguine! I need two different blood samples - The first one from the necromancer's pure blood chamber. ... ",
			"I was barred from the premises. For my research! Shameful! I'm a martyr to the cause - oh, the second sample you said? ...",
			"The second sample you must retrieve from the sacrificial chamber in the ancient vampire crypts, first floor, far west. ...",
			"Take these two sterilised vials, one for each blood basin. Oh, I wish I could go myself! Come back


 operand1: Some(Direct(ZMM27)), operand2: Some(Direct(ZMM24)), operand3: Some(IndirectScaledDisplaced(RDX, Four, 791063378, Some(OperandSize::Dword), None)), operand4: None, lock: false, rounding_mode: None, merge_mode: Some(MergeMode::Zero), sae: false, mask: Some(MaskReg::K3), broadcast: Some(BroadcastMode::Broadcast1To16) }, &[98, 98, 61, 211, 172, 28, 149, 82, 171, 38, 47], OperandSize::Qword)
}

use std::collections::HashMap;
use std::sync::mpsc::{Receiver, Sender};
use std::sync::{Arc, Mutex};
use std::thread;

use libconcentratord::signals;
use libconcentratord::signals::Signal;
use libconcentratord::{commands, events, jitqueue, reset};
use libloragw_sx1302::hal;

use super::super::{concentrator, config, handler, wrapper};

pub fn run(
    config: &config::Configuration,
    stop_send: Sender<Signal>,
    stop_receive: Arc<Receiver<Signal>>,
) -> Result<Signal, String> {
    info!(
        "Starting Concentratord SX1302 (version: {}, docs: {})",
        config::VERSION,
        "https://www.chirpstack.io/concentratord/"
    );

    // reset concentrator
    reset::reset().expect("concentrator reset failed");

    // setup concentrator
    concentrator::board_setconf(&config)?;
    concentrator::timestamp_setconf(&config)?;
    concentrator::txgain_setconf(&config)?;
    concentrator::rxrf_setconf(&config)?;
    concentrator::rxif_setconf(&config)?;
    concentrator::start()?;

    // setup static location
    handler::gps::set_static_gps_coords(
        config.gateway.location.latitude,
        config.gateway.location.longitude,
        config.gateway.location.altitude,
    );

    // get concentrator eui
    let gateway_id = concentrator::get_eui().unwrap();

    info!(
        "Gateway ID retrieved, gateway_id: {:x?}",
        hex::encode(gateway_id)
    );

    // setup jit queue
    let queue: jitqueue::Queue<wrapper::TxPacket> = jitqueue::Queue::new(32);
    let queue = Arc::new(Mutex::new(queue));

    // setup zeromq
    events::bind_socket(&config.concentratord.api.event_bind).expect("bind event socket error");
    let rep_sock = commands::get_socket(&config.concentratord.api.command_bind)
        .expect("bind command socket error");

    // setup threads
    let mut signal_pool = signals::SignalPool::new();
    let mut threads: Vec<thread::JoinHandle<()>> = vec![];

    // uplink thread
    threads.push(thread::spawn({
        let gateway_id = gateway_id.clone();
        let stop_receive = signal_pool.new_receiver();

        move || {
            handler::uplink::handle_loop(&gateway_id, stop_receive);
        }
    }));

    // jit thread
    threads.push(thread::spawn({
        let queue = Arc::clone(&queue);
        let antenna_gain = config.gateway.antenna_gain;
        let stop_receive = signal_pool.new_receiver();

        move || {
            handler::jit::jit_loop(queue, antenna_gain, stop_receive);
        }
    }));

    // command thread
    threads.push(thread::spawn({
        let vendor_config = config.gateway.model_config.clone();
        let gateway_id = gateway_id.clone();
        let stop_receive = signal_pool.new_receiver();
        let stop_send = stop_send.clone();

        move || {
            handler::command::handle_loop(