<!doctype html>
<html lang="en">

<head>
  <!-- Import style -->
  <link rel="stylesheet" href="../../index.css" />
  <link rel="stylesheet" href="../../prettify.css" />
  <!-- Import Vue 3 -->
  <script src="../../vue.global.prod.js"></script>
  <!-- Import component library -->
  <script src="../../index.full.min.js"></script>
  <script src="../../prettify.js"></script>
  <meta charset="UTF-8">
  <title>Coverage</title>
</head>

<body>
  <div id="app" class="common-layout">
    <el-container>
      <el-header>
        <el-row :gutter="10">
          <el-col :span="5">
            <el-space :size="size" spacer="">
              <div><el-text class="mx-1 ">
                  <el-link type="primary" :href="relativeHome">
                    <h2>&lt;</h2>
                  </el-link>
                </el-text></div>
              <div><el-text class="mx-1 "><h2>{{title}}</h2></el-text></div>
              <div><el-text class="mx-1 "
                  type="info"></el-text></div>
            </el-space>
          </el-col>
          <el-col :span="3">
            <el-space :size="size" spacer="">
              <div><el-text class="mx-1 ">
                  <h2>{{file.summary.functions.pct}}%</h2>
                </el-text></div>
              <div><el-text class="mx-1 ">Functions</el-text></div>
              <div><el-text class="mx-1 "
                  type="info">{{file.summary.functions.covered}}/{{file.summary.functions.total}}</el-text></div>
            </el-space>
          </el-col>
          <el-col :span="3">
            <el-space :size="size" spacer="">
              <div><el-text class="mx-1 ">
                  <h2>{{file.summary.branches.pct}}%</h2>
                </el-text></div>
              <div><el-text class="mx-1 ">Branches</el-text></div>
              <div><el-text class="mx-1 "
                  type="info">{{file.summary.branches.covered}}/{{file.summary.branches.total}}</el-text></div>
            </el-space>
          </el-col>
          <el-col :span="3">
            <el-space :size="size" spacer="">
              <div><el-text class="mx-1 ">
                  <h2>{{file.summary.lines.pct}}%</h2>
                </el-text></div>
              <div><el-text class="mx-1 ">Lines</el-text></div>
              <div><el-text class="mx-1 "
                  type="info">{{file.summary.lines.covered}}/{{file.summary.lines.total}}</el-text></div>
            </el-space>
          </el-col>
        </el-row>
        <el-divider />
      </el-header>
      <el-main>
        <el-row>
        </el-row>
        <pre>
          <table class="coverage">
            <tr>
              <td class="line-count quiet">
                <pre class="prettyprint lang-js">
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">6x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
                </pre>
        </td>
        <td class="text">
          <pre class="prettyprint linenums lang-js">
/** 
 * 语言解析纯函数（与 `warmup.html` 的语言判定语义对齐，无副作用，便于单测）。 
 * 
 * warmup.html 逻辑：`i18nAutoDetect ? convertDetectedLanguage(?lang &gt; localStorage &gt; navigator) : &#39;zh-CN&#39;`， 
 * 再取 `locales[lang]`（回退 zh-CN）。native 侧 L3 无 WebView，`localStorage` 够不着， 
 * 故语言来源为 `preferredLanguage`（显式）→ 系统语言（best-effort，等价 navigator.language）→ `zh-CN`。 
 */ 
 
/** 语言归一化：精确匹配 → 前缀匹配（en-GB→en-US / zh-TW→zh-CN）→ 回退 `zh-CN`。 */ 
export function convertDetectedLanguage(lng: string, supported: string[]): string { 
  if (lng.length === 0) { 
    return &#39;zh-CN&#39;; 
  } 
  if (supported.indexOf(lng) !== -1) { 
    return lng; 
  } 
  const prefix: string = lng.split(&#39;-&#39;)[0]; 
  for (let i = 0; i &lt; supported.length; i++) { 
    if (supported[i].indexOf(prefix) === 0) { 
      return supported[i]; 
    } 
  } 
  return &#39;zh-CN&#39;; 
} 
 
/** 
 * 解析当前应预取的语言（与 warmup.html 逐行对齐）。 
 * 
 * warmup.html: `lang = i18nAutoDetect ? convertDetectedLanguage(langParam || localStorage || navigator) : &#39;zh-CN&#39;` 
 * ——即 `i18nAutoDetect=false` 时**无视任何语言偏好，恒 `zh-CN`**（真实页此时也恒渲染 zh-CN， 
 * 预热其他语言纯属缓存 miss）。故 `preferredLanguage` 仅在 `i18nAutoDetect=true` 时生效， 
 * 扮演 warmup.html 中 `langParam`（最高优先级）的角色；系统语言扮演 `localStorage || navigator`。 
 * 
 * @param preferred `config.preferredLanguage`，仅 `i18nAutoDetect=true` 时非空优先 
 * @param i18nAutoDetect manifest 的 `i18nAutoDetect` 
 * @param systemLang 系统语言（best-effort，由调用方注入以保持本函数纯净） 
 * @param supported manifest 的 `supportedLngs` 
 */ 
export function resolveLang( 
  preferred: string | null, 
  i18nAutoDetect: boolean, 
  systemLang: string, 
  supported: string[] 
): string { 
  // i18nAutoDetect=false → 恒 zh-CN（与 warmup.html / 真实页一致） 
  if (!i18nAutoDetect) { 
    return &#39;zh-CN&#39;; 
  } 
  const raw: string = (preferred !== null &amp;&amp; preferred.length &gt; 0) ? preferred : systemLang; 
  return convertDetectedLanguage(raw, supported); 
} 
 
/** 取语言资源列表；`locales[lang]` 缺失时回退 `locales[&#39;zh-CN&#39;]`，再缺失返回空数组。 */ 
export function pickLocaleAssets(locales: Record&lt;string, string[]&gt; | undefined, lang: string): string[] { 
  if (locales === undefined || locales === null) { 
    return []; 
  } 
  const picked: string[] | undefined = locales[lang]; 
  if (picked !== undefined &amp;&amp; picked !== null) { 
    return picked; 
  } 
  const fallback: string[] | undefined = locales[&#39;zh-CN&#39;]; 
  return fallback !== undefined &amp;&amp; fallback !== null ? fallback : []; 
} 

              </pre>
        </td>
        </tr>
        </table>
        </pre>
      </el-main>
      <el-footer align="middle" class="footer">
        Code coverage generated by <el-link href="https://github.com/SMAT-Lab/bjc" type="primary"
          target="_blank">bjc</el-link> at {{date}}
      </el-footer>
    </el-container>
  </div>
</body>

<script>
  const App = {
    data() {
      return {"date":"Fri Jul 31 2026 16:52:24 GMT+0800 (China Standard Time)","file":{"version":"bjc v1.0.0","versionCode":10000,"path":"/Users/qinzhiqiang/Git/frontend/h5-in-app-integration/harmonyos-arkts/tencentqianwebview/src/main/ets/internal/prewarm/LangUtil.ets","hash":"22424c0de8bcdf7a9d52110cd6cd6235bcb36f6ffce9a6befdc4610c1551bc2a","lineCnt":65,"count":0,"projectPath":"/Users/qinzhiqiang/Git/frontend/h5-in-app-integration/harmonyos-arkts","functions":[{"name":"convertDetectedLanguage","count":7,"regions":[{"startLoc":{"line":10,"col":1},"endLoc":{"line":24,"col":2},"count":7,"ignored":0},{"startLoc":{"line":18,"col":3},"endLoc":{"line":22,"col":4},"count":7,"ignored":0},{"startLoc":{"line":11,"col":25},"endLoc":{"line":13,"col":4},"count":1,"ignored":0},{"startLoc":{"line":14,"col":38},"endLoc":{"line":16,"col":4},"count":2,"ignored":0},{"startLoc":{"line":19,"col":45},"endLoc":{"line":21,"col":6},"count":3,"ignored":0},{"startLoc":{"line":23,"col":3},"endLoc":{"line":24,"col":2},"count":1,"ignored":0}],"branches":[{"startLoc":{"line":11,"col":7},"endLoc":{"line":11,"col":23},"trueCount":1,"falseCount":6,"group":[],"ignored":0},{"startLoc":{"line":14,"col":7},"endLoc":{"line":14,"col":36},"trueCount":2,"falseCount":4,"group":[],"ignored":0},{"startLoc":{"line":19,"col":9},"endLoc":{"line":19,"col":43},"trueCount":3,"falseCount":4,"group":[],"ignored":0}],"ignored":0,"index":0},{"name":"resolveLang","count":4,"regions":[{"startLoc":{"line":39,"col":1},"endLoc":{"line":51,"col":2},"count":4,"ignored":0},{"startLoc":{"line":46,"col":24},"endLoc":{"line":48,"col":4},"count":2,"ignored":0},{"startLoc":{"line":49,"col":3},"endLoc":{"line":51,"col":2},"count":2,"ignored":0}],"branches":[{"startLoc":{"line":46,"col":7},"endLoc":{"line":46,"col":22},"trueCount":2,"falseCount":2,"group":[],"ignored":0},{"startLoc":{"line":49,"col":23},"endLoc":{"line":49,"col":92},"trueCount":1,"falseCount":1,"group":[],"ignored":0}],"ignored":0,"index":1},{"name":"pickLocaleAssets","count":3,"regions":[{"startLoc":{"line":54,"col":1},"endLoc":{"line":64,"col":2},"count":3,"ignored":0},{"startLoc":{"line":55,"col":50},"endLoc":{"line":57,"col":4},"count":1,"ignored":0},{"startLoc":{"line":59,"col":48},"endLoc":{"line":61,"col":4},"count":1,"ignored":0},{"startLoc":{"line":62,"col":3},"endLoc":{"line":64,"col":2},"count":1,"ignored":0}],"branches":[{"startLoc":{"line":55,"col":7},"endLoc":{"line":55,"col":48},"trueCount":1,"falseCount":2,"group":[],"ignored":0},{"startLoc":{"line":59,"col":7},"endLoc":{"line":59,"col":46},"trueCount":1,"falseCount":1,"group":[],"ignored":0},{"startLoc":{"line":63,"col":10},"endLoc":{"line":63,"col":69},"trueCount":1,"falseCount":0,"group":[],"ignored":0}],"ignored":0,"index":2}],"exeLine":{"0":10,"1":11,"2":12,"3":14,"4":15,"5":17,"6":18,"7":19,"8":20,"9":23,"10":39,"11":40,"12":41,"13":42,"14":43,"15":44,"16":46,"17":47,"18":49,"19":50,"20":54,"21":55,"22":56,"23":58,"24":59,"25":60,"26":62,"27":63},"summary":{"lines":{"total":28,"covered":28,"pct":100,"executedLineCount":[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,7,1,-1,6,2,-1,7,7,7,3,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,4,4,4,4,4,4,-1,4,2,-1,2,2,-1,-1,-1,3,3,1,-1,3,2,1,-1,1,1,-1,-1]},"functions":{"total":3,"covered":3,"pct":100},"branches":{"total":16,"covered":15,"pct":93.75}}},"title":"LangUtil.ets.html","relativeHome":"../../index.html"};
    }
  };

  const app = Vue.createApp(App);
  app.use(ElementPlus);
  app.mount("#app");

  window.onload = function () {
    prettyPrint();
  }
</script>

<style scoped>
  table.coverage {
    width: 100%;
    border-collapse: collapse;
    margin: 10px 0 0 0;
    padding: 0;
  }

  table.coverage td {
    margin: 0;
    padding: 0;
    vertical-align: top;
  }

  table.coverage td.line-count {
    width: 12%;
    text-align: right;
    padding: 0 5px 0 20px;
  }

  table.coverage td.line-coverage {
    text-align: right;
    padding-right: 10px;
    min-width: 20px;
  }

  table.coverage td span.cline-any {
    display: inline-block;
    padding: 0 5px;
    width: 100%;
    height: 18px;
  }

  .low,
  .cline-no {
    background: #FCE1E5
  }

  .high,
  .cline-yes {
    background: rgb(230, 245, 208)
  }

  span.cline-neutral {
    background: #eaeaea;
  }

  pre.prettyprint {
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
  }

  .el-main {
    box-sizing: border-box;
    display: block;
    flex: 1;
    flex-basis: auto;
    overflow: auto;
    padding: var(--el-main-padding)
  }

  .el-container {
    min-height: 100vh;
    height: 100%;
  }

  .footer {
    font-size: small;
  }

  .el-row {
    margin-bottom: 20px;
  }

  .el-row:last-child {
    margin-bottom: 0;
  }

  .el-col {
    border-radius: 4px;
  }

  .green {
    color: var(--el-color-success);
  }

  .red {
    color: var(--el-color-error);
  }

  .linenums li {
    height: 18px;
    line-height: 18px;
  }

  li.L0,
  li.L1,
  li.L2,
  li.L3,
  li.L5,
  li.L6,
  li.L7,
  li.L8 {
    list-style-type: decimal
  }

  .el-col-5 {
    max-width: 100%;
  }

  .el-col-3 {
    max-width: 100%;
  }

</style>

</html>