@solaqua/gji 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3951,8 +3951,8 @@ var require_graceful_fs = __commonJS({
3951
3951
  fs6.createReadStream = createReadStream;
3952
3952
  fs6.createWriteStream = createWriteStream;
3953
3953
  var fs$readFile = fs6.readFile;
3954
- fs6.readFile = readFile3;
3955
- function readFile3(path9, options, cb) {
3954
+ fs6.readFile = readFile4;
3955
+ function readFile4(path9, options, cb) {
3956
3956
  if (typeof options === "function")
3957
3957
  cb = options, options = null;
3958
3958
  return go$readFile(path9, options, cb);
@@ -3968,8 +3968,8 @@ var require_graceful_fs = __commonJS({
3968
3968
  }
3969
3969
  }
3970
3970
  var fs$writeFile = fs6.writeFile;
3971
- fs6.writeFile = writeFile4;
3972
- function writeFile4(path9, data, options, cb) {
3971
+ fs6.writeFile = writeFile5;
3972
+ function writeFile5(path9, data, options, cb) {
3973
3973
  if (typeof options === "function")
3974
3974
  cb = options, options = null;
3975
3975
  return go$writeFile(path9, data, options, cb);
@@ -5386,7 +5386,7 @@ var require_minimist = __commonJS({
5386
5386
  var require_rc = __commonJS({
5387
5387
  "node_modules/.pnpm/rc@1.2.8/node_modules/rc/index.js"(exports, module) {
5388
5388
  var cc = require_utils();
5389
- var join6 = __require("path").join;
5389
+ var join7 = __require("path").join;
5390
5390
  var deepExtend = require_deep_extend();
5391
5391
  var etc = "/etc";
5392
5392
  var win = process.platform === "win32";
@@ -5411,15 +5411,15 @@ var require_rc = __commonJS({
5411
5411
  }
5412
5412
  if (!win)
5413
5413
  [
5414
- join6(etc, name, "config"),
5415
- join6(etc, name + "rc")
5414
+ join7(etc, name, "config"),
5415
+ join7(etc, name + "rc")
5416
5416
  ].forEach(addConfigFile);
5417
5417
  if (home)
5418
5418
  [
5419
- join6(home, ".config", name, "config"),
5420
- join6(home, ".config", name),
5421
- join6(home, "." + name, "config"),
5422
- join6(home, "." + name + "rc")
5419
+ join7(home, ".config", name, "config"),
5420
+ join7(home, ".config", name),
5421
+ join7(home, "." + name, "config"),
5422
+ join7(home, "." + name + "rc")
5423
5423
  ].forEach(addConfigFile);
5424
5424
  addConfigFile(cc.find("." + name + "rc"));
5425
5425
  if (env4.config) addConfigFile(env4.config);
@@ -5925,8 +5925,8 @@ var require_graceful_fs2 = __commonJS({
5925
5925
  fs6.createReadStream = createReadStream;
5926
5926
  fs6.createWriteStream = createWriteStream;
5927
5927
  var fs$readFile = fs6.readFile;
5928
- fs6.readFile = readFile3;
5929
- function readFile3(path9, options, cb) {
5928
+ fs6.readFile = readFile4;
5929
+ function readFile4(path9, options, cb) {
5930
5930
  if (typeof options === "function")
5931
5931
  cb = options, options = null;
5932
5932
  return go$readFile(path9, options, cb);
@@ -5942,8 +5942,8 @@ var require_graceful_fs2 = __commonJS({
5942
5942
  }
5943
5943
  }
5944
5944
  var fs$writeFile = fs6.writeFile;
5945
- fs6.writeFile = writeFile4;
5946
- function writeFile4(path9, data, options, cb) {
5945
+ fs6.writeFile = writeFile5;
5946
+ function writeFile5(path9, data, options, cb) {
5947
5947
  if (typeof options === "function")
5948
5948
  cb = options, options = null;
5949
5949
  return go$writeFile(path9, data, options, cb);
@@ -6757,11 +6757,11 @@ var require_util = __commonJS({
6757
6757
  if (files.includes("node_modules") || files.includes("package.json") || files.includes("package.json5") || files.includes("package.yaml") || files.includes("pnpm-workspace.yaml")) {
6758
6758
  return name2;
6759
6759
  }
6760
- const dirname7 = path9.dirname(name2);
6761
- if (dirname7 === name2) {
6760
+ const dirname8 = path9.dirname(name2);
6761
+ if (dirname8 === name2) {
6762
6762
  return original;
6763
6763
  }
6764
- return find(dirname7, original);
6764
+ return find(dirname8, original);
6765
6765
  } catch (error) {
6766
6766
  if (name2 === original) {
6767
6767
  if (error.code === "ENOENT") {
@@ -9422,7 +9422,7 @@ var require_picocolors = __commonJS({
9422
9422
  });
9423
9423
 
9424
9424
  // src/index.ts
9425
- import { homedir as homedir4 } from "node:os";
9425
+ import { homedir as homedir5 } from "node:os";
9426
9426
 
9427
9427
  // src/config.ts
9428
9428
  import { mkdir, readFile, writeFile } from "node:fs/promises";
@@ -9739,7 +9739,7 @@ var retryifyAsync = (fn, options) => {
9739
9739
  throw error;
9740
9740
  const delay2 = Math.round(interval * Math.random());
9741
9741
  if (delay2 > 0) {
9742
- const delayPromise = new Promise((resolve3) => setTimeout(resolve3, delay2));
9742
+ const delayPromise = new Promise((resolve4) => setTimeout(resolve4, delay2));
9743
9743
  return delayPromise.then(() => attempt.apply(void 0, args));
9744
9744
  } else {
9745
9745
  return attempt.apply(void 0, args);
@@ -9998,14 +9998,14 @@ var Temp = {
9998
9998
  }
9999
9999
  },
10000
10000
  truncate: (filePath) => {
10001
- const basename6 = path2.basename(filePath);
10002
- if (basename6.length <= LIMIT_BASENAME_LENGTH)
10001
+ const basename7 = path2.basename(filePath);
10002
+ if (basename7.length <= LIMIT_BASENAME_LENGTH)
10003
10003
  return filePath;
10004
- const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename6);
10004
+ const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename7);
10005
10005
  if (!truncable)
10006
10006
  return filePath;
10007
- const truncationLength = basename6.length - LIMIT_BASENAME_LENGTH;
10008
- return `${filePath.slice(0, -basename6.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
10007
+ const truncationLength = basename7.length - LIMIT_BASENAME_LENGTH;
10008
+ return `${filePath.slice(0, -basename7.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
10009
10009
  }
10010
10010
  };
10011
10011
  node_default(Temp.purgeSyncAll);
@@ -11305,14 +11305,14 @@ var TimeoutError = class extends Error {
11305
11305
 
11306
11306
  // node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/timeout.js
11307
11307
  async function timeout(request, init, abortController, options) {
11308
- return new Promise((resolve3, reject) => {
11308
+ return new Promise((resolve4, reject) => {
11309
11309
  const timeoutId = setTimeout(() => {
11310
11310
  if (abortController) {
11311
11311
  abortController.abort();
11312
11312
  }
11313
11313
  reject(new TimeoutError(request));
11314
11314
  }, options.timeout);
11315
- void options.fetch(request, init).then(resolve3).catch(reject).then(() => {
11315
+ void options.fetch(request, init).then(resolve4).catch(reject).then(() => {
11316
11316
  clearTimeout(timeoutId);
11317
11317
  });
11318
11318
  });
@@ -11320,7 +11320,7 @@ async function timeout(request, init, abortController, options) {
11320
11320
 
11321
11321
  // node_modules/.pnpm/ky@1.14.3/node_modules/ky/distribution/utils/delay.js
11322
11322
  async function delay(ms, { signal }) {
11323
- return new Promise((resolve3, reject) => {
11323
+ return new Promise((resolve4, reject) => {
11324
11324
  if (signal) {
11325
11325
  signal.throwIfAborted();
11326
11326
  signal.addEventListener("abort", abortHandler, { once: true });
@@ -11331,7 +11331,7 @@ async function delay(ms, { signal }) {
11331
11331
  }
11332
11332
  const timeoutId = setTimeout(() => {
11333
11333
  signal?.removeEventListener("abort", abortHandler);
11334
- resolve3();
11334
+ resolve4();
11335
11335
  }, ms);
11336
11336
  });
11337
11337
  }
@@ -13027,142 +13027,511 @@ function updateNotifier(options) {
13027
13027
  return updateNotifier2;
13028
13028
  }
13029
13029
 
13030
- // node_modules/.pnpm/@clack+core@0.5.0/node_modules/@clack/core/dist/index.mjs
13031
- var import_sisteransi = __toESM(require_src(), 1);
13032
- import { stdin as j, stdout as M } from "node:process";
13033
- var import_picocolors = __toESM(require_picocolors(), 1);
13034
- import O from "node:readline";
13035
- import { Writable as X } from "node:stream";
13036
- function DD({ onlyFirst: e2 = false } = {}) {
13037
- const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
13038
- return new RegExp(t, e2 ? void 0 : "g");
13039
- }
13040
- var uD = DD();
13041
- function P(e2) {
13042
- if (typeof e2 != "string") throw new TypeError(`Expected a \`string\`, got \`${typeof e2}\``);
13043
- return e2.replace(uD, "");
13030
+ // src/back.ts
13031
+ import { access } from "node:fs/promises";
13032
+ import { basename as basename2 } from "node:path";
13033
+
13034
+ // src/hooks.ts
13035
+ import { spawn as spawn2 } from "node:child_process";
13036
+ async function runHook(hookCmd, cwd, context, stderr) {
13037
+ if (!hookCmd) return;
13038
+ const interpolated = interpolate(hookCmd, context);
13039
+ await new Promise((resolve4) => {
13040
+ const child = spawn2(interpolated, {
13041
+ cwd,
13042
+ shell: true,
13043
+ stdio: ["ignore", "inherit", "pipe"],
13044
+ env: {
13045
+ ...process.env,
13046
+ GJI_BRANCH: context.branch ?? "",
13047
+ GJI_PATH: context.path,
13048
+ GJI_REPO: context.repo
13049
+ }
13050
+ });
13051
+ child.stderr.on("data", (chunk) => {
13052
+ stderr(chunk.toString());
13053
+ });
13054
+ child.on("close", (code) => {
13055
+ if (code !== 0) {
13056
+ stderr(`gji: hook exited with code ${code}: ${interpolated}
13057
+ `);
13058
+ }
13059
+ resolve4();
13060
+ });
13061
+ child.on("error", (err) => {
13062
+ stderr(`gji: hook failed to start: ${err.message}
13063
+ `);
13064
+ resolve4();
13065
+ });
13066
+ });
13044
13067
  }
13045
- function L(e2) {
13046
- return e2 && e2.__esModule && Object.prototype.hasOwnProperty.call(e2, "default") ? e2.default : e2;
13068
+ function interpolate(template, context) {
13069
+ return template.replace(/\{\{branch\}\}/g, context.branch ?? "").replace(/\{\{path\}\}/g, context.path).replace(/\{\{repo\}\}/g, context.repo);
13047
13070
  }
13048
- var W = { exports: {} };
13049
- (function(e2) {
13050
- var u2 = {};
13051
- e2.exports = u2, u2.eastAsianWidth = function(F2) {
13052
- var s = F2.charCodeAt(0), i = F2.length == 2 ? F2.charCodeAt(1) : 0, D2 = s;
13053
- return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D2 = s << 10 | i, D2 += 65536), D2 == 12288 || 65281 <= D2 && D2 <= 65376 || 65504 <= D2 && D2 <= 65510 ? "F" : D2 == 8361 || 65377 <= D2 && D2 <= 65470 || 65474 <= D2 && D2 <= 65479 || 65482 <= D2 && D2 <= 65487 || 65490 <= D2 && D2 <= 65495 || 65498 <= D2 && D2 <= 65500 || 65512 <= D2 && D2 <= 65518 ? "H" : 4352 <= D2 && D2 <= 4447 || 4515 <= D2 && D2 <= 4519 || 4602 <= D2 && D2 <= 4607 || 9001 <= D2 && D2 <= 9002 || 11904 <= D2 && D2 <= 11929 || 11931 <= D2 && D2 <= 12019 || 12032 <= D2 && D2 <= 12245 || 12272 <= D2 && D2 <= 12283 || 12289 <= D2 && D2 <= 12350 || 12353 <= D2 && D2 <= 12438 || 12441 <= D2 && D2 <= 12543 || 12549 <= D2 && D2 <= 12589 || 12593 <= D2 && D2 <= 12686 || 12688 <= D2 && D2 <= 12730 || 12736 <= D2 && D2 <= 12771 || 12784 <= D2 && D2 <= 12830 || 12832 <= D2 && D2 <= 12871 || 12880 <= D2 && D2 <= 13054 || 13056 <= D2 && D2 <= 19903 || 19968 <= D2 && D2 <= 42124 || 42128 <= D2 && D2 <= 42182 || 43360 <= D2 && D2 <= 43388 || 44032 <= D2 && D2 <= 55203 || 55216 <= D2 && D2 <= 55238 || 55243 <= D2 && D2 <= 55291 || 63744 <= D2 && D2 <= 64255 || 65040 <= D2 && D2 <= 65049 || 65072 <= D2 && D2 <= 65106 || 65108 <= D2 && D2 <= 65126 || 65128 <= D2 && D2 <= 65131 || 110592 <= D2 && D2 <= 110593 || 127488 <= D2 && D2 <= 127490 || 127504 <= D2 && D2 <= 127546 || 127552 <= D2 && D2 <= 127560 || 127568 <= D2 && D2 <= 127569 || 131072 <= D2 && D2 <= 194367 || 177984 <= D2 && D2 <= 196605 || 196608 <= D2 && D2 <= 262141 ? "W" : 32 <= D2 && D2 <= 126 || 162 <= D2 && D2 <= 163 || 165 <= D2 && D2 <= 166 || D2 == 172 || D2 == 175 || 10214 <= D2 && D2 <= 10221 || 10629 <= D2 && D2 <= 10630 ? "Na" : D2 == 161 || D2 == 164 || 167 <= D2 && D2 <= 168 || D2 == 170 || 173 <= D2 && D2 <= 174 || 176 <= D2 && D2 <= 180 || 182 <= D2 && D2 <= 186 || 188 <= D2 && D2 <= 191 || D2 == 198 || D2 == 208 || 215 <= D2 && D2 <= 216 || 222 <= D2 && D2 <= 225 || D2 == 230 || 232 <= D2 && D2 <= 234 || 236 <= D2 && D2 <= 237 || D2 == 240 || 242 <= D2 && D2 <= 243 || 247 <= D2 && D2 <= 250 || D2 == 252 || D2 == 254 || D2 == 257 || D2 == 273 || D2 == 275 || D2 == 283 || 294 <= D2 && D2 <= 295 || D2 == 299 || 305 <= D2 && D2 <= 307 || D2 == 312 || 319 <= D2 && D2 <= 322 || D2 == 324 || 328 <= D2 && D2 <= 331 || D2 == 333 || 338 <= D2 && D2 <= 339 || 358 <= D2 && D2 <= 359 || D2 == 363 || D2 == 462 || D2 == 464 || D2 == 466 || D2 == 468 || D2 == 470 || D2 == 472 || D2 == 474 || D2 == 476 || D2 == 593 || D2 == 609 || D2 == 708 || D2 == 711 || 713 <= D2 && D2 <= 715 || D2 == 717 || D2 == 720 || 728 <= D2 && D2 <= 731 || D2 == 733 || D2 == 735 || 768 <= D2 && D2 <= 879 || 913 <= D2 && D2 <= 929 || 931 <= D2 && D2 <= 937 || 945 <= D2 && D2 <= 961 || 963 <= D2 && D2 <= 969 || D2 == 1025 || 1040 <= D2 && D2 <= 1103 || D2 == 1105 || D2 == 8208 || 8211 <= D2 && D2 <= 8214 || 8216 <= D2 && D2 <= 8217 || 8220 <= D2 && D2 <= 8221 || 8224 <= D2 && D2 <= 8226 || 8228 <= D2 && D2 <= 8231 || D2 == 8240 || 8242 <= D2 && D2 <= 8243 || D2 == 8245 || D2 == 8251 || D2 == 8254 || D2 == 8308 || D2 == 8319 || 8321 <= D2 && D2 <= 8324 || D2 == 8364 || D2 == 8451 || D2 == 8453 || D2 == 8457 || D2 == 8467 || D2 == 8470 || 8481 <= D2 && D2 <= 8482 || D2 == 8486 || D2 == 8491 || 8531 <= D2 && D2 <= 8532 || 8539 <= D2 && D2 <= 8542 || 8544 <= D2 && D2 <= 8555 || 8560 <= D2 && D2 <= 8569 || D2 == 8585 || 8592 <= D2 && D2 <= 8601 || 8632 <= D2 && D2 <= 8633 || D2 == 8658 || D2 == 8660 || D2 == 8679 || D2 == 8704 || 8706 <= D2 && D2 <= 8707 || 8711 <= D2 && D2 <= 8712 || D2 == 8715 || D2 == 8719 || D2 == 8721 || D2 == 8725 || D2 == 8730 || 8733 <= D2 && D2 <= 8736 || D2 == 8739 || D2 == 8741 || 8743 <= D2 && D2 <= 8748 || D2 == 8750 || 8756 <= D2 && D2 <= 8759 || 8764 <= D2 && D2 <= 8765 || D2 == 8776 || D2 == 8780 || D2 == 8786 || 8800 <= D2 && D2 <= 8801 || 8804 <= D2 && D2 <= 8807 || 8810 <= D2 && D2 <= 8811 || 8814 <= D2 && D2 <= 8815 || 8834 <= D2 && D2 <= 8835 || 8838 <= D2 && D2 <= 8839 || D2 == 8853 || D2 == 8857 || D2 == 8869 || D2 == 8895 || D2 == 8978 || 9312 <= D2 && D2 <= 9449 || 9451 <= D2 && D2 <= 9547 || 9552 <= D2 && D2 <= 9587 || 9600 <= D2 && D2 <= 9615 || 9618 <= D2 && D2 <= 9621 || 9632 <= D2 && D2 <= 9633 || 9635 <= D2 && D2 <= 9641 || 9650 <= D2 && D2 <= 9651 || 9654 <= D2 && D2 <= 9655 || 9660 <= D2 && D2 <= 9661 || 9664 <= D2 && D2 <= 9665 || 9670 <= D2 && D2 <= 9672 || D2 == 9675 || 9678 <= D2 && D2 <= 9681 || 9698 <= D2 && D2 <= 9701 || D2 == 9711 || 9733 <= D2 && D2 <= 9734 || D2 == 9737 || 9742 <= D2 && D2 <= 9743 || 9748 <= D2 && D2 <= 9749 || D2 == 9756 || D2 == 9758 || D2 == 9792 || D2 == 9794 || 9824 <= D2 && D2 <= 9825 || 9827 <= D2 && D2 <= 9829 || 9831 <= D2 && D2 <= 9834 || 9836 <= D2 && D2 <= 9837 || D2 == 9839 || 9886 <= D2 && D2 <= 9887 || 9918 <= D2 && D2 <= 9919 || 9924 <= D2 && D2 <= 9933 || 9935 <= D2 && D2 <= 9953 || D2 == 9955 || 9960 <= D2 && D2 <= 9983 || D2 == 10045 || D2 == 10071 || 10102 <= D2 && D2 <= 10111 || 11093 <= D2 && D2 <= 11097 || 12872 <= D2 && D2 <= 12879 || 57344 <= D2 && D2 <= 63743 || 65024 <= D2 && D2 <= 65039 || D2 == 65533 || 127232 <= D2 && D2 <= 127242 || 127248 <= D2 && D2 <= 127277 || 127280 <= D2 && D2 <= 127337 || 127344 <= D2 && D2 <= 127386 || 917760 <= D2 && D2 <= 917999 || 983040 <= D2 && D2 <= 1048573 || 1048576 <= D2 && D2 <= 1114109 ? "A" : "N";
13054
- }, u2.characterLength = function(F2) {
13055
- var s = this.eastAsianWidth(F2);
13056
- return s == "F" || s == "W" || s == "A" ? 2 : 1;
13057
- };
13058
- function t(F2) {
13059
- return F2.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
13071
+ function extractHooks(config) {
13072
+ const raw = config.hooks;
13073
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
13074
+ return {};
13060
13075
  }
13061
- u2.length = function(F2) {
13062
- for (var s = t(F2), i = 0, D2 = 0; D2 < s.length; D2++) i = i + this.characterLength(s[D2]);
13063
- return i;
13064
- }, u2.slice = function(F2, s, i) {
13065
- textLen = u2.length(F2), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
13066
- for (var D2 = "", C2 = 0, n = t(F2), E = 0; E < n.length; E++) {
13067
- var a = n[E], o2 = u2.length(a);
13068
- if (C2 >= s - (o2 == 2 ? 1 : 0)) if (C2 + o2 <= i) D2 += a;
13069
- else break;
13070
- C2 += o2;
13071
- }
13072
- return D2;
13076
+ const hooks = raw;
13077
+ return {
13078
+ afterCreate: typeof hooks.afterCreate === "string" ? hooks.afterCreate : void 0,
13079
+ afterEnter: typeof hooks.afterEnter === "string" ? hooks.afterEnter : void 0,
13080
+ beforeRemove: typeof hooks.beforeRemove === "string" ? hooks.beforeRemove : void 0
13073
13081
  };
13074
- })(W);
13075
- var tD = W.exports;
13076
- var eD = L(tD);
13077
- var FD = function() {
13078
- return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
13079
- };
13080
- var sD = L(FD);
13081
- function p(e2, u2 = {}) {
13082
- if (typeof e2 != "string" || e2.length === 0 || (u2 = { ambiguousIsNarrow: true, ...u2 }, e2 = P(e2), e2.length === 0)) return 0;
13083
- e2 = e2.replace(sD(), " ");
13084
- const t = u2.ambiguousIsNarrow ? 1 : 2;
13085
- let F2 = 0;
13086
- for (const s of e2) {
13087
- const i = s.codePointAt(0);
13088
- if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879) continue;
13089
- switch (eD.eastAsianWidth(s)) {
13090
- case "F":
13091
- case "W":
13092
- F2 += 2;
13093
- break;
13094
- case "A":
13095
- F2 += t;
13096
- break;
13097
- default:
13098
- F2 += 1;
13099
- }
13082
+ }
13083
+
13084
+ // src/history.ts
13085
+ import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
13086
+ import { homedir as homedir2 } from "node:os";
13087
+ import { dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
13088
+ var HISTORY_FILE_NAME = "history.json";
13089
+ var MAX_HISTORY_ENTRIES = 50;
13090
+ function HISTORY_FILE_PATH(home = homedir2()) {
13091
+ const configDir = process.env.GJI_CONFIG_DIR;
13092
+ if (configDir) {
13093
+ return join2(resolve2(configDir), HISTORY_FILE_NAME);
13100
13094
  }
13101
- return F2;
13095
+ return join2(home, GLOBAL_CONFIG_DIRECTORY, HISTORY_FILE_NAME);
13102
13096
  }
13103
- var w = 10;
13104
- var N = (e2 = 0) => (u2) => `\x1B[${u2 + e2}m`;
13105
- var I = (e2 = 0) => (u2) => `\x1B[${38 + e2};5;${u2}m`;
13106
- var R = (e2 = 0) => (u2, t, F2) => `\x1B[${38 + e2};2;${u2};${t};${F2}m`;
13107
- var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
13108
- Object.keys(r.modifier);
13109
- var iD = Object.keys(r.color);
13110
- var CD = Object.keys(r.bgColor);
13111
- [...iD, ...CD];
13112
- function rD() {
13113
- const e2 = /* @__PURE__ */ new Map();
13114
- for (const [u2, t] of Object.entries(r)) {
13115
- for (const [F2, s] of Object.entries(t)) r[F2] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F2] = r[F2], e2.set(s[0], s[1]);
13116
- Object.defineProperty(r, u2, { value: t, enumerable: false });
13097
+ async function loadHistory(home = homedir2()) {
13098
+ const path9 = HISTORY_FILE_PATH(home);
13099
+ try {
13100
+ const raw = await readFile2(path9, "utf8");
13101
+ const parsed = JSON.parse(raw);
13102
+ if (!Array.isArray(parsed)) return [];
13103
+ return parsed.filter(isHistoryEntry);
13104
+ } catch {
13105
+ return [];
13117
13106
  }
13118
- return Object.defineProperty(r, "codes", { value: e2, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = N(), r.color.ansi256 = I(), r.color.ansi16m = R(), r.bgColor.ansi = N(w), r.bgColor.ansi256 = I(w), r.bgColor.ansi16m = R(w), Object.defineProperties(r, { rgbToAnsi256: { value: (u2, t, F2) => u2 === t && t === F2 ? u2 < 8 ? 16 : u2 > 248 ? 231 : Math.round((u2 - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u2 / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F2 / 255 * 5), enumerable: false }, hexToRgb: { value: (u2) => {
13119
- const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u2.toString(16));
13120
- if (!t) return [0, 0, 0];
13121
- let [F2] = t;
13122
- F2.length === 3 && (F2 = [...F2].map((i) => i + i).join(""));
13123
- const s = Number.parseInt(F2, 16);
13124
- return [s >> 16 & 255, s >> 8 & 255, s & 255];
13125
- }, enumerable: false }, hexToAnsi256: { value: (u2) => r.rgbToAnsi256(...r.hexToRgb(u2)), enumerable: false }, ansi256ToAnsi: { value: (u2) => {
13126
- if (u2 < 8) return 30 + u2;
13127
- if (u2 < 16) return 90 + (u2 - 8);
13128
- let t, F2, s;
13129
- if (u2 >= 232) t = ((u2 - 232) * 10 + 8) / 255, F2 = t, s = t;
13130
- else {
13131
- u2 -= 16;
13132
- const C2 = u2 % 36;
13133
- t = Math.floor(u2 / 36) / 5, F2 = Math.floor(C2 / 6) / 5, s = C2 % 6 / 5;
13107
+ }
13108
+ async function appendHistory(path9, branch, home = homedir2()) {
13109
+ const historyPath = HISTORY_FILE_PATH(home);
13110
+ const existing = await loadHistory(home);
13111
+ if (existing.length > 0 && existing[0].path === path9) {
13112
+ return;
13113
+ }
13114
+ const entry = { branch, path: path9, timestamp: Date.now() };
13115
+ const next = [entry, ...existing].slice(0, MAX_HISTORY_ENTRIES);
13116
+ await mkdir2(dirname2(historyPath), { recursive: true });
13117
+ await writeFile2(historyPath, `${JSON.stringify(next, null, 2)}
13118
+ `, "utf8");
13119
+ }
13120
+ function isHistoryEntry(value) {
13121
+ return typeof value === "object" && value !== null && "path" in value && typeof value.path === "string" && "timestamp" in value && typeof value.timestamp === "number";
13122
+ }
13123
+
13124
+ // src/repo.ts
13125
+ import { basename, dirname as dirname3, isAbsolute, join as join3, resolve as resolve3 } from "node:path";
13126
+ import { homedir as homedir3 } from "node:os";
13127
+
13128
+ // src/git.ts
13129
+ import { execFile } from "node:child_process";
13130
+ import { promisify as promisify2 } from "node:util";
13131
+ var execFileAsync = promisify2(execFile);
13132
+ async function runGit(cwd, args) {
13133
+ try {
13134
+ const { stdout } = await execFileAsync("git", args, { cwd });
13135
+ return stdout.trim();
13136
+ } catch (error) {
13137
+ const message = error instanceof Error ? error.message : String(error);
13138
+ throw new Error(`Git command failed in '${cwd}': ${message}`);
13139
+ }
13140
+ }
13141
+ async function readWorktreeHealth(cwd) {
13142
+ const { stdout } = await execFileAsync("git", ["status", "--porcelain=v2", "--branch"], { cwd });
13143
+ return parseWorktreeHealth(stdout);
13144
+ }
13145
+ async function isDirtyWorktree(cwd) {
13146
+ const health = await readWorktreeHealth(cwd);
13147
+ return health.status === "dirty";
13148
+ }
13149
+ async function isBranchMergedInto(cwd, branch, base = "HEAD") {
13150
+ try {
13151
+ await execFileAsync("git", ["merge-base", "--is-ancestor", branch, base], { cwd });
13152
+ return true;
13153
+ } catch (error) {
13154
+ if (hasExitCode(error, 1)) {
13155
+ return false;
13134
13156
  }
13135
- const i = Math.max(t, F2, s) * 2;
13136
- if (i === 0) return 30;
13137
- let D2 = 30 + (Math.round(s) << 2 | Math.round(F2) << 1 | Math.round(t));
13138
- return i === 2 && (D2 += 60), D2;
13139
- }, enumerable: false }, rgbToAnsi: { value: (u2, t, F2) => r.ansi256ToAnsi(r.rgbToAnsi256(u2, t, F2)), enumerable: false }, hexToAnsi: { value: (u2) => r.ansi256ToAnsi(r.hexToAnsi256(u2)), enumerable: false } }), r;
13157
+ throw error;
13158
+ }
13140
13159
  }
13141
- var ED = rD();
13142
- var d = /* @__PURE__ */ new Set(["\x1B", "\x9B"]);
13143
- var oD = 39;
13144
- var y = "\x07";
13145
- var V = "[";
13146
- var nD = "]";
13147
- var G = "m";
13148
- var _ = `${nD}8;;`;
13149
- var z = (e2) => `${d.values().next().value}${V}${e2}${G}`;
13150
- var K = (e2) => `${d.values().next().value}${_}${e2}${y}`;
13151
- var aD = (e2) => e2.split(" ").map((u2) => p(u2));
13152
- var k = (e2, u2, t) => {
13153
- const F2 = [...u2];
13154
- let s = false, i = false, D2 = p(P(e2[e2.length - 1]));
13155
- for (const [C2, n] of F2.entries()) {
13156
- const E = p(n);
13157
- if (D2 + E <= t ? e2[e2.length - 1] += n : (e2.push(n), D2 = 0), d.has(n) && (s = true, i = F2.slice(C2 + 1).join("").startsWith(_)), s) {
13158
- i ? n === y && (s = false, i = false) : n === G && (s = false);
13160
+ async function resolveRemoteDefaultBranch(cwd, remote) {
13161
+ const { stdout } = await execFileAsync("git", ["ls-remote", "--symref", remote, "HEAD"], { cwd });
13162
+ const refLine = stdout.split("\n").find((line) => line.startsWith("ref: refs/heads/"));
13163
+ if (!refLine) {
13164
+ return null;
13165
+ }
13166
+ const match = /^ref: refs\/heads\/(.+)\tHEAD$/.exec(refLine);
13167
+ return match?.[1] ?? null;
13168
+ }
13169
+ async function readBranchLastCommitTimestamp(cwd, branch) {
13170
+ try {
13171
+ const { stdout } = await execFileAsync("git", ["log", "-1", "--format=%ct", branch], { cwd });
13172
+ const timestamp = Number(stdout.trim());
13173
+ return Number.isFinite(timestamp) ? timestamp : null;
13174
+ } catch {
13175
+ return null;
13176
+ }
13177
+ }
13178
+ function parseWorktreeHealth(output) {
13179
+ let ahead = 0;
13180
+ let behind = 0;
13181
+ let hasUpstream = false;
13182
+ let hasAb = false;
13183
+ let dirty = false;
13184
+ for (const line of output.split("\n").filter(Boolean)) {
13185
+ if (line.startsWith("# branch.upstream ")) {
13186
+ hasUpstream = true;
13159
13187
  continue;
13160
13188
  }
13161
- D2 += E, D2 === t && C2 < F2.length - 1 && (e2.push(""), D2 = 0);
13189
+ if (line.startsWith("# branch.ab ")) {
13190
+ const match = /^# branch\.ab \+(\d+) -(\d+)$/.exec(line);
13191
+ if (!match) {
13192
+ throw new Error(`Unexpected branch.ab output: '${line}'`);
13193
+ }
13194
+ hasAb = true;
13195
+ ahead = Number(match[1]);
13196
+ behind = Number(match[2]);
13197
+ continue;
13198
+ }
13199
+ if (!line.startsWith("# ")) {
13200
+ dirty = true;
13201
+ }
13162
13202
  }
13163
- !D2 && e2[e2.length - 1].length > 0 && e2.length > 1 && (e2[e2.length - 2] += e2.pop());
13164
- };
13165
- var hD = (e2) => {
13203
+ return {
13204
+ ahead,
13205
+ behind,
13206
+ hasUpstream,
13207
+ upstreamGone: hasUpstream && !hasAb,
13208
+ status: dirty ? "dirty" : "clean"
13209
+ };
13210
+ }
13211
+ function hasExitCode(error, code) {
13212
+ return error instanceof Error && "code" in error && error.code === code;
13213
+ }
13214
+
13215
+ // src/repo.ts
13216
+ async function detectRepository(cwd) {
13217
+ const currentRoot = await runGit(cwd, ["rev-parse", "--show-toplevel"]);
13218
+ const rawCommonDir = await runGit(cwd, ["rev-parse", "--git-common-dir"]);
13219
+ const gitCommonDir = isAbsolute(rawCommonDir) ? rawCommonDir : resolve3(currentRoot, rawCommonDir);
13220
+ const repoRoot = dirname3(gitCommonDir);
13221
+ return {
13222
+ currentRoot,
13223
+ gitCommonDir,
13224
+ isWorktree: currentRoot !== repoRoot,
13225
+ repoName: basename(repoRoot),
13226
+ repoRoot
13227
+ };
13228
+ }
13229
+ function resolveWorktreePath(repoRoot, branch, basePath) {
13230
+ const segments = branch.split("/").filter(Boolean);
13231
+ if (segments.length === 0) {
13232
+ throw new Error("Branch name must not be empty.");
13233
+ }
13234
+ if (segments.some((segment) => segment === "." || segment === "..")) {
13235
+ throw new Error(`Branch name '${branch}' contains an invalid path segment.`);
13236
+ }
13237
+ const base = basePath ? expandTildeInPath(basePath) : join3(dirname3(repoRoot), "worktrees", basename(repoRoot));
13238
+ return join3(base, ...segments);
13239
+ }
13240
+ function validateBranchName(name) {
13241
+ if (name.length === 0) {
13242
+ return "Branch name must not be empty.";
13243
+ }
13244
+ if (/[\x00-\x1f\x7f ~^:?*[\\\s]/.test(name)) {
13245
+ return `Branch name '${name}' contains an invalid character.`;
13246
+ }
13247
+ if (name.startsWith("-")) {
13248
+ return `Branch name '${name}' must not start with a dash.`;
13249
+ }
13250
+ if (name.startsWith("/") || name.endsWith("/") || name.includes("//")) {
13251
+ return `Branch name '${name}' has invalid slash placement.`;
13252
+ }
13253
+ if (name.includes("..")) {
13254
+ return `Branch name '${name}' must not contain '..'.`;
13255
+ }
13256
+ if (name.endsWith(".")) {
13257
+ return `Branch name '${name}' must not end with '.'.`;
13258
+ }
13259
+ if (name.includes("@{")) {
13260
+ return `Branch name '${name}' must not contain '@{'.`;
13261
+ }
13262
+ if (name === "@") {
13263
+ return "Branch name cannot be '@'.";
13264
+ }
13265
+ for (const segment of name.split("/")) {
13266
+ if (segment.startsWith(".")) {
13267
+ return `Branch name '${name}' contains a path component starting with '.'.`;
13268
+ }
13269
+ if (segment.endsWith(".lock")) {
13270
+ return `Branch name '${name}' contains a path component ending with '.lock'.`;
13271
+ }
13272
+ }
13273
+ return null;
13274
+ }
13275
+ function expandTildeInPath(p2) {
13276
+ if (p2 === "~") return homedir3();
13277
+ if (p2.startsWith("~/")) return join3(homedir3(), p2.slice(2));
13278
+ return p2;
13279
+ }
13280
+ async function listWorktrees(cwd) {
13281
+ const [output, currentRoot] = await Promise.all([
13282
+ runGit(cwd, ["worktree", "list", "--porcelain"]),
13283
+ runGit(cwd, ["rev-parse", "--show-toplevel"])
13284
+ ]);
13285
+ const entries = output.split("\n\n").filter(Boolean);
13286
+ return entries.map((entry) => {
13287
+ const path9 = findPorcelainValue(entry, "worktree");
13288
+ const branchRef = findOptionalPorcelainValue(entry, "branch");
13289
+ return {
13290
+ branch: branchRef ? branchRef.replace("refs/heads/", "") : null,
13291
+ isCurrent: path9 === currentRoot,
13292
+ path: path9
13293
+ };
13294
+ });
13295
+ }
13296
+ function sortByCurrentFirst(worktrees) {
13297
+ return [...worktrees].sort((a, b3) => {
13298
+ if (a.isCurrent && !b3.isCurrent) return -1;
13299
+ if (!a.isCurrent && b3.isCurrent) return 1;
13300
+ return 0;
13301
+ });
13302
+ }
13303
+ function findPorcelainValue(block, key) {
13304
+ const value = findOptionalPorcelainValue(block, key);
13305
+ if (!value) {
13306
+ throw new Error(`Missing '${key}' in git worktree output.`);
13307
+ }
13308
+ return value;
13309
+ }
13310
+ function findOptionalPorcelainValue(block, key) {
13311
+ const line = block.split("\n").find((candidate) => candidate.startsWith(`${key} `));
13312
+ if (!line) {
13313
+ return null;
13314
+ }
13315
+ return line.slice(key.length + 1);
13316
+ }
13317
+
13318
+ // src/shell-handoff.ts
13319
+ import { writeFile as writeFile3 } from "node:fs/promises";
13320
+ async function writeShellOutput(envVar, value, stdout) {
13321
+ const output = `${value}
13322
+ `;
13323
+ if (process.env[envVar]) {
13324
+ await writeFile3(process.env[envVar], output, "utf8");
13325
+ return;
13326
+ }
13327
+ stdout(output);
13328
+ }
13329
+
13330
+ // src/back.ts
13331
+ var BACK_OUTPUT_FILE_ENV = "GJI_BACK_OUTPUT_FILE";
13332
+ async function runBackCommand(options) {
13333
+ const history = await loadHistory(options.home);
13334
+ const steps = options.n ?? 1;
13335
+ if (steps < 1) {
13336
+ options.stderr("gji back: step count must be at least 1\n");
13337
+ return 1;
13338
+ }
13339
+ let found = 0;
13340
+ let target;
13341
+ for (const entry of history) {
13342
+ if (entry.path === options.cwd) continue;
13343
+ try {
13344
+ await access(entry.path);
13345
+ found++;
13346
+ if (found === steps) {
13347
+ target = entry;
13348
+ break;
13349
+ }
13350
+ } catch {
13351
+ }
13352
+ }
13353
+ if (!target) {
13354
+ options.stderr("gji back: no previous worktree in history\n");
13355
+ options.stderr("Hint: Use 'gji go', 'gji new', or 'gji pr' to navigate between worktrees\n");
13356
+ return 1;
13357
+ }
13358
+ try {
13359
+ const repository = await detectRepository(target.path);
13360
+ const config = await loadEffectiveConfig(repository.repoRoot, options.home, options.stderr);
13361
+ const hooks = extractHooks(config);
13362
+ await runHook(
13363
+ hooks.afterEnter,
13364
+ target.path,
13365
+ { branch: target.branch ?? void 0, path: target.path, repo: basename2(repository.repoRoot) },
13366
+ options.stderr
13367
+ );
13368
+ } catch {
13369
+ }
13370
+ await appendHistory(target.path, target.branch, options.home);
13371
+ await writeShellOutput(BACK_OUTPUT_FILE_ENV, target.path, options.stdout);
13372
+ return 0;
13373
+ }
13374
+ function formatHistoryList(history, cwd) {
13375
+ const branchWidth = Math.max(
13376
+ "BRANCH".length,
13377
+ ...history.map((e2) => (e2.branch ?? "(detached)").length)
13378
+ );
13379
+ const lines = [" " + "BRANCH".padEnd(branchWidth) + " WHEN PATH"];
13380
+ for (const entry of history) {
13381
+ const isCurrent = entry.path === cwd;
13382
+ const branch = (entry.branch ?? "(detached)").padEnd(branchWidth);
13383
+ const when = formatAge(entry.timestamp).padEnd(10);
13384
+ lines.push(`${isCurrent ? "*" : " "} ${branch} ${when} ${entry.path}`);
13385
+ }
13386
+ return lines.join("\n") + "\n";
13387
+ }
13388
+ function formatAge(timestamp) {
13389
+ const seconds = Math.floor((Date.now() - timestamp) / 1e3);
13390
+ if (seconds < 60) return "just now";
13391
+ const minutes = Math.floor(seconds / 60);
13392
+ if (minutes < 60) return `${minutes}m ago`;
13393
+ const hours = Math.floor(minutes / 60);
13394
+ if (hours < 24) return `${hours}h ago`;
13395
+ const days = Math.floor(hours / 24);
13396
+ return `${days}d ago`;
13397
+ }
13398
+
13399
+ // node_modules/.pnpm/@clack+core@0.5.0/node_modules/@clack/core/dist/index.mjs
13400
+ var import_sisteransi = __toESM(require_src(), 1);
13401
+ import { stdin as j, stdout as M } from "node:process";
13402
+ var import_picocolors = __toESM(require_picocolors(), 1);
13403
+ import O from "node:readline";
13404
+ import { Writable as X } from "node:stream";
13405
+ function DD({ onlyFirst: e2 = false } = {}) {
13406
+ const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
13407
+ return new RegExp(t, e2 ? void 0 : "g");
13408
+ }
13409
+ var uD = DD();
13410
+ function P(e2) {
13411
+ if (typeof e2 != "string") throw new TypeError(`Expected a \`string\`, got \`${typeof e2}\``);
13412
+ return e2.replace(uD, "");
13413
+ }
13414
+ function L(e2) {
13415
+ return e2 && e2.__esModule && Object.prototype.hasOwnProperty.call(e2, "default") ? e2.default : e2;
13416
+ }
13417
+ var W = { exports: {} };
13418
+ (function(e2) {
13419
+ var u2 = {};
13420
+ e2.exports = u2, u2.eastAsianWidth = function(F2) {
13421
+ var s = F2.charCodeAt(0), i = F2.length == 2 ? F2.charCodeAt(1) : 0, D2 = s;
13422
+ return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D2 = s << 10 | i, D2 += 65536), D2 == 12288 || 65281 <= D2 && D2 <= 65376 || 65504 <= D2 && D2 <= 65510 ? "F" : D2 == 8361 || 65377 <= D2 && D2 <= 65470 || 65474 <= D2 && D2 <= 65479 || 65482 <= D2 && D2 <= 65487 || 65490 <= D2 && D2 <= 65495 || 65498 <= D2 && D2 <= 65500 || 65512 <= D2 && D2 <= 65518 ? "H" : 4352 <= D2 && D2 <= 4447 || 4515 <= D2 && D2 <= 4519 || 4602 <= D2 && D2 <= 4607 || 9001 <= D2 && D2 <= 9002 || 11904 <= D2 && D2 <= 11929 || 11931 <= D2 && D2 <= 12019 || 12032 <= D2 && D2 <= 12245 || 12272 <= D2 && D2 <= 12283 || 12289 <= D2 && D2 <= 12350 || 12353 <= D2 && D2 <= 12438 || 12441 <= D2 && D2 <= 12543 || 12549 <= D2 && D2 <= 12589 || 12593 <= D2 && D2 <= 12686 || 12688 <= D2 && D2 <= 12730 || 12736 <= D2 && D2 <= 12771 || 12784 <= D2 && D2 <= 12830 || 12832 <= D2 && D2 <= 12871 || 12880 <= D2 && D2 <= 13054 || 13056 <= D2 && D2 <= 19903 || 19968 <= D2 && D2 <= 42124 || 42128 <= D2 && D2 <= 42182 || 43360 <= D2 && D2 <= 43388 || 44032 <= D2 && D2 <= 55203 || 55216 <= D2 && D2 <= 55238 || 55243 <= D2 && D2 <= 55291 || 63744 <= D2 && D2 <= 64255 || 65040 <= D2 && D2 <= 65049 || 65072 <= D2 && D2 <= 65106 || 65108 <= D2 && D2 <= 65126 || 65128 <= D2 && D2 <= 65131 || 110592 <= D2 && D2 <= 110593 || 127488 <= D2 && D2 <= 127490 || 127504 <= D2 && D2 <= 127546 || 127552 <= D2 && D2 <= 127560 || 127568 <= D2 && D2 <= 127569 || 131072 <= D2 && D2 <= 194367 || 177984 <= D2 && D2 <= 196605 || 196608 <= D2 && D2 <= 262141 ? "W" : 32 <= D2 && D2 <= 126 || 162 <= D2 && D2 <= 163 || 165 <= D2 && D2 <= 166 || D2 == 172 || D2 == 175 || 10214 <= D2 && D2 <= 10221 || 10629 <= D2 && D2 <= 10630 ? "Na" : D2 == 161 || D2 == 164 || 167 <= D2 && D2 <= 168 || D2 == 170 || 173 <= D2 && D2 <= 174 || 176 <= D2 && D2 <= 180 || 182 <= D2 && D2 <= 186 || 188 <= D2 && D2 <= 191 || D2 == 198 || D2 == 208 || 215 <= D2 && D2 <= 216 || 222 <= D2 && D2 <= 225 || D2 == 230 || 232 <= D2 && D2 <= 234 || 236 <= D2 && D2 <= 237 || D2 == 240 || 242 <= D2 && D2 <= 243 || 247 <= D2 && D2 <= 250 || D2 == 252 || D2 == 254 || D2 == 257 || D2 == 273 || D2 == 275 || D2 == 283 || 294 <= D2 && D2 <= 295 || D2 == 299 || 305 <= D2 && D2 <= 307 || D2 == 312 || 319 <= D2 && D2 <= 322 || D2 == 324 || 328 <= D2 && D2 <= 331 || D2 == 333 || 338 <= D2 && D2 <= 339 || 358 <= D2 && D2 <= 359 || D2 == 363 || D2 == 462 || D2 == 464 || D2 == 466 || D2 == 468 || D2 == 470 || D2 == 472 || D2 == 474 || D2 == 476 || D2 == 593 || D2 == 609 || D2 == 708 || D2 == 711 || 713 <= D2 && D2 <= 715 || D2 == 717 || D2 == 720 || 728 <= D2 && D2 <= 731 || D2 == 733 || D2 == 735 || 768 <= D2 && D2 <= 879 || 913 <= D2 && D2 <= 929 || 931 <= D2 && D2 <= 937 || 945 <= D2 && D2 <= 961 || 963 <= D2 && D2 <= 969 || D2 == 1025 || 1040 <= D2 && D2 <= 1103 || D2 == 1105 || D2 == 8208 || 8211 <= D2 && D2 <= 8214 || 8216 <= D2 && D2 <= 8217 || 8220 <= D2 && D2 <= 8221 || 8224 <= D2 && D2 <= 8226 || 8228 <= D2 && D2 <= 8231 || D2 == 8240 || 8242 <= D2 && D2 <= 8243 || D2 == 8245 || D2 == 8251 || D2 == 8254 || D2 == 8308 || D2 == 8319 || 8321 <= D2 && D2 <= 8324 || D2 == 8364 || D2 == 8451 || D2 == 8453 || D2 == 8457 || D2 == 8467 || D2 == 8470 || 8481 <= D2 && D2 <= 8482 || D2 == 8486 || D2 == 8491 || 8531 <= D2 && D2 <= 8532 || 8539 <= D2 && D2 <= 8542 || 8544 <= D2 && D2 <= 8555 || 8560 <= D2 && D2 <= 8569 || D2 == 8585 || 8592 <= D2 && D2 <= 8601 || 8632 <= D2 && D2 <= 8633 || D2 == 8658 || D2 == 8660 || D2 == 8679 || D2 == 8704 || 8706 <= D2 && D2 <= 8707 || 8711 <= D2 && D2 <= 8712 || D2 == 8715 || D2 == 8719 || D2 == 8721 || D2 == 8725 || D2 == 8730 || 8733 <= D2 && D2 <= 8736 || D2 == 8739 || D2 == 8741 || 8743 <= D2 && D2 <= 8748 || D2 == 8750 || 8756 <= D2 && D2 <= 8759 || 8764 <= D2 && D2 <= 8765 || D2 == 8776 || D2 == 8780 || D2 == 8786 || 8800 <= D2 && D2 <= 8801 || 8804 <= D2 && D2 <= 8807 || 8810 <= D2 && D2 <= 8811 || 8814 <= D2 && D2 <= 8815 || 8834 <= D2 && D2 <= 8835 || 8838 <= D2 && D2 <= 8839 || D2 == 8853 || D2 == 8857 || D2 == 8869 || D2 == 8895 || D2 == 8978 || 9312 <= D2 && D2 <= 9449 || 9451 <= D2 && D2 <= 9547 || 9552 <= D2 && D2 <= 9587 || 9600 <= D2 && D2 <= 9615 || 9618 <= D2 && D2 <= 9621 || 9632 <= D2 && D2 <= 9633 || 9635 <= D2 && D2 <= 9641 || 9650 <= D2 && D2 <= 9651 || 9654 <= D2 && D2 <= 9655 || 9660 <= D2 && D2 <= 9661 || 9664 <= D2 && D2 <= 9665 || 9670 <= D2 && D2 <= 9672 || D2 == 9675 || 9678 <= D2 && D2 <= 9681 || 9698 <= D2 && D2 <= 9701 || D2 == 9711 || 9733 <= D2 && D2 <= 9734 || D2 == 9737 || 9742 <= D2 && D2 <= 9743 || 9748 <= D2 && D2 <= 9749 || D2 == 9756 || D2 == 9758 || D2 == 9792 || D2 == 9794 || 9824 <= D2 && D2 <= 9825 || 9827 <= D2 && D2 <= 9829 || 9831 <= D2 && D2 <= 9834 || 9836 <= D2 && D2 <= 9837 || D2 == 9839 || 9886 <= D2 && D2 <= 9887 || 9918 <= D2 && D2 <= 9919 || 9924 <= D2 && D2 <= 9933 || 9935 <= D2 && D2 <= 9953 || D2 == 9955 || 9960 <= D2 && D2 <= 9983 || D2 == 10045 || D2 == 10071 || 10102 <= D2 && D2 <= 10111 || 11093 <= D2 && D2 <= 11097 || 12872 <= D2 && D2 <= 12879 || 57344 <= D2 && D2 <= 63743 || 65024 <= D2 && D2 <= 65039 || D2 == 65533 || 127232 <= D2 && D2 <= 127242 || 127248 <= D2 && D2 <= 127277 || 127280 <= D2 && D2 <= 127337 || 127344 <= D2 && D2 <= 127386 || 917760 <= D2 && D2 <= 917999 || 983040 <= D2 && D2 <= 1048573 || 1048576 <= D2 && D2 <= 1114109 ? "A" : "N";
13423
+ }, u2.characterLength = function(F2) {
13424
+ var s = this.eastAsianWidth(F2);
13425
+ return s == "F" || s == "W" || s == "A" ? 2 : 1;
13426
+ };
13427
+ function t(F2) {
13428
+ return F2.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
13429
+ }
13430
+ u2.length = function(F2) {
13431
+ for (var s = t(F2), i = 0, D2 = 0; D2 < s.length; D2++) i = i + this.characterLength(s[D2]);
13432
+ return i;
13433
+ }, u2.slice = function(F2, s, i) {
13434
+ textLen = u2.length(F2), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
13435
+ for (var D2 = "", C2 = 0, n = t(F2), E = 0; E < n.length; E++) {
13436
+ var a = n[E], o2 = u2.length(a);
13437
+ if (C2 >= s - (o2 == 2 ? 1 : 0)) if (C2 + o2 <= i) D2 += a;
13438
+ else break;
13439
+ C2 += o2;
13440
+ }
13441
+ return D2;
13442
+ };
13443
+ })(W);
13444
+ var tD = W.exports;
13445
+ var eD = L(tD);
13446
+ var FD = function() {
13447
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
13448
+ };
13449
+ var sD = L(FD);
13450
+ function p(e2, u2 = {}) {
13451
+ if (typeof e2 != "string" || e2.length === 0 || (u2 = { ambiguousIsNarrow: true, ...u2 }, e2 = P(e2), e2.length === 0)) return 0;
13452
+ e2 = e2.replace(sD(), " ");
13453
+ const t = u2.ambiguousIsNarrow ? 1 : 2;
13454
+ let F2 = 0;
13455
+ for (const s of e2) {
13456
+ const i = s.codePointAt(0);
13457
+ if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879) continue;
13458
+ switch (eD.eastAsianWidth(s)) {
13459
+ case "F":
13460
+ case "W":
13461
+ F2 += 2;
13462
+ break;
13463
+ case "A":
13464
+ F2 += t;
13465
+ break;
13466
+ default:
13467
+ F2 += 1;
13468
+ }
13469
+ }
13470
+ return F2;
13471
+ }
13472
+ var w = 10;
13473
+ var N = (e2 = 0) => (u2) => `\x1B[${u2 + e2}m`;
13474
+ var I = (e2 = 0) => (u2) => `\x1B[${38 + e2};5;${u2}m`;
13475
+ var R = (e2 = 0) => (u2, t, F2) => `\x1B[${38 + e2};2;${u2};${t};${F2}m`;
13476
+ var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
13477
+ Object.keys(r.modifier);
13478
+ var iD = Object.keys(r.color);
13479
+ var CD = Object.keys(r.bgColor);
13480
+ [...iD, ...CD];
13481
+ function rD() {
13482
+ const e2 = /* @__PURE__ */ new Map();
13483
+ for (const [u2, t] of Object.entries(r)) {
13484
+ for (const [F2, s] of Object.entries(t)) r[F2] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F2] = r[F2], e2.set(s[0], s[1]);
13485
+ Object.defineProperty(r, u2, { value: t, enumerable: false });
13486
+ }
13487
+ return Object.defineProperty(r, "codes", { value: e2, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = N(), r.color.ansi256 = I(), r.color.ansi16m = R(), r.bgColor.ansi = N(w), r.bgColor.ansi256 = I(w), r.bgColor.ansi16m = R(w), Object.defineProperties(r, { rgbToAnsi256: { value: (u2, t, F2) => u2 === t && t === F2 ? u2 < 8 ? 16 : u2 > 248 ? 231 : Math.round((u2 - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u2 / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F2 / 255 * 5), enumerable: false }, hexToRgb: { value: (u2) => {
13488
+ const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u2.toString(16));
13489
+ if (!t) return [0, 0, 0];
13490
+ let [F2] = t;
13491
+ F2.length === 3 && (F2 = [...F2].map((i) => i + i).join(""));
13492
+ const s = Number.parseInt(F2, 16);
13493
+ return [s >> 16 & 255, s >> 8 & 255, s & 255];
13494
+ }, enumerable: false }, hexToAnsi256: { value: (u2) => r.rgbToAnsi256(...r.hexToRgb(u2)), enumerable: false }, ansi256ToAnsi: { value: (u2) => {
13495
+ if (u2 < 8) return 30 + u2;
13496
+ if (u2 < 16) return 90 + (u2 - 8);
13497
+ let t, F2, s;
13498
+ if (u2 >= 232) t = ((u2 - 232) * 10 + 8) / 255, F2 = t, s = t;
13499
+ else {
13500
+ u2 -= 16;
13501
+ const C2 = u2 % 36;
13502
+ t = Math.floor(u2 / 36) / 5, F2 = Math.floor(C2 / 6) / 5, s = C2 % 6 / 5;
13503
+ }
13504
+ const i = Math.max(t, F2, s) * 2;
13505
+ if (i === 0) return 30;
13506
+ let D2 = 30 + (Math.round(s) << 2 | Math.round(F2) << 1 | Math.round(t));
13507
+ return i === 2 && (D2 += 60), D2;
13508
+ }, enumerable: false }, rgbToAnsi: { value: (u2, t, F2) => r.ansi256ToAnsi(r.rgbToAnsi256(u2, t, F2)), enumerable: false }, hexToAnsi: { value: (u2) => r.ansi256ToAnsi(r.hexToAnsi256(u2)), enumerable: false } }), r;
13509
+ }
13510
+ var ED = rD();
13511
+ var d = /* @__PURE__ */ new Set(["\x1B", "\x9B"]);
13512
+ var oD = 39;
13513
+ var y = "\x07";
13514
+ var V = "[";
13515
+ var nD = "]";
13516
+ var G = "m";
13517
+ var _ = `${nD}8;;`;
13518
+ var z = (e2) => `${d.values().next().value}${V}${e2}${G}`;
13519
+ var K = (e2) => `${d.values().next().value}${_}${e2}${y}`;
13520
+ var aD = (e2) => e2.split(" ").map((u2) => p(u2));
13521
+ var k = (e2, u2, t) => {
13522
+ const F2 = [...u2];
13523
+ let s = false, i = false, D2 = p(P(e2[e2.length - 1]));
13524
+ for (const [C2, n] of F2.entries()) {
13525
+ const E = p(n);
13526
+ if (D2 + E <= t ? e2[e2.length - 1] += n : (e2.push(n), D2 = 0), d.has(n) && (s = true, i = F2.slice(C2 + 1).join("").startsWith(_)), s) {
13527
+ i ? n === y && (s = false, i = false) : n === G && (s = false);
13528
+ continue;
13529
+ }
13530
+ D2 += E, D2 === t && C2 < F2.length - 1 && (e2.push(""), D2 = 0);
13531
+ }
13532
+ !D2 && e2[e2.length - 1].length > 0 && e2.length > 1 && (e2[e2.length - 2] += e2.pop());
13533
+ };
13534
+ var hD = (e2) => {
13166
13535
  const u2 = e2.split(" ");
13167
13536
  let t = u2.length;
13168
13537
  for (; t > 0 && !(p(u2[t - 1]) > 0); ) t--;
@@ -13568,133 +13937,46 @@ ${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${impor
13568
13937
  }, render() {
13569
13938
  const r2 = `${import_picocolors2.default.gray(o)}
13570
13939
  ${b2(this.state)} ${t.message}
13571
- `, i = (s, c) => {
13572
- const a = this.value.includes(s.value);
13573
- return c && a ? n(s, "active-selected") : a ? n(s, "selected") : n(s, c ? "active" : "inactive");
13574
- };
13575
- switch (this.state) {
13576
- case "submit":
13577
- return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
13578
- case "cancel": {
13579
- const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
13580
- return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
13581
- ${import_picocolors2.default.gray(o)}` : ""}`;
13582
- }
13583
- case "error": {
13584
- const s = this.error.split(`
13585
- `).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
13586
- `);
13587
- return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
13588
- ${import_picocolors2.default.yellow(o)} `)}
13589
- ${s}
13590
- `;
13591
- }
13592
- default:
13593
- return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
13594
- ${import_picocolors2.default.cyan(o)} `)}
13595
- ${import_picocolors2.default.cyan(d2)}
13596
- `;
13597
- }
13598
- } }).prompt();
13599
- };
13600
- var Ie = (t = "") => {
13601
- process.stdout.write(`${import_picocolors2.default.gray(ue)} ${t}
13602
- `);
13603
- };
13604
- var Se = (t = "") => {
13605
- process.stdout.write(`${import_picocolors2.default.gray(o)}
13606
- ${import_picocolors2.default.gray(d2)} ${t}
13607
-
13608
- `);
13609
- };
13610
- var J2 = `${import_picocolors2.default.gray(o)} `;
13611
-
13612
- // src/git.ts
13613
- import { execFile } from "node:child_process";
13614
- import { promisify as promisify2 } from "node:util";
13615
- var execFileAsync = promisify2(execFile);
13616
- async function runGit(cwd, args) {
13617
- try {
13618
- const { stdout } = await execFileAsync("git", args, { cwd });
13619
- return stdout.trim();
13620
- } catch (error) {
13621
- const message = error instanceof Error ? error.message : String(error);
13622
- throw new Error(`Git command failed in '${cwd}': ${message}`);
13623
- }
13624
- }
13625
- async function readWorktreeHealth(cwd) {
13626
- const { stdout } = await execFileAsync("git", ["status", "--porcelain=v2", "--branch"], { cwd });
13627
- return parseWorktreeHealth(stdout);
13628
- }
13629
- async function isDirtyWorktree(cwd) {
13630
- const health = await readWorktreeHealth(cwd);
13631
- return health.status === "dirty";
13632
- }
13633
- async function isBranchMergedInto(cwd, branch, base = "HEAD") {
13634
- try {
13635
- await execFileAsync("git", ["merge-base", "--is-ancestor", branch, base], { cwd });
13636
- return true;
13637
- } catch (error) {
13638
- if (hasExitCode(error, 1)) {
13639
- return false;
13640
- }
13641
- throw error;
13642
- }
13643
- }
13644
- async function resolveRemoteDefaultBranch(cwd, remote) {
13645
- const { stdout } = await execFileAsync("git", ["ls-remote", "--symref", remote, "HEAD"], { cwd });
13646
- const refLine = stdout.split("\n").find((line) => line.startsWith("ref: refs/heads/"));
13647
- if (!refLine) {
13648
- return null;
13649
- }
13650
- const match = /^ref: refs\/heads\/(.+)\tHEAD$/.exec(refLine);
13651
- return match?.[1] ?? null;
13652
- }
13653
- async function readBranchLastCommitTimestamp(cwd, branch) {
13654
- try {
13655
- const { stdout } = await execFileAsync("git", ["log", "-1", "--format=%ct", branch], { cwd });
13656
- const timestamp = Number(stdout.trim());
13657
- return Number.isFinite(timestamp) ? timestamp : null;
13658
- } catch {
13659
- return null;
13660
- }
13661
- }
13662
- function parseWorktreeHealth(output) {
13663
- let ahead = 0;
13664
- let behind = 0;
13665
- let hasUpstream = false;
13666
- let hasAb = false;
13667
- let dirty = false;
13668
- for (const line of output.split("\n").filter(Boolean)) {
13669
- if (line.startsWith("# branch.upstream ")) {
13670
- hasUpstream = true;
13671
- continue;
13672
- }
13673
- if (line.startsWith("# branch.ab ")) {
13674
- const match = /^# branch\.ab \+(\d+) -(\d+)$/.exec(line);
13675
- if (!match) {
13676
- throw new Error(`Unexpected branch.ab output: '${line}'`);
13940
+ `, i = (s, c) => {
13941
+ const a = this.value.includes(s.value);
13942
+ return c && a ? n(s, "active-selected") : a ? n(s, "selected") : n(s, c ? "active" : "inactive");
13943
+ };
13944
+ switch (this.state) {
13945
+ case "submit":
13946
+ return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
13947
+ case "cancel": {
13948
+ const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
13949
+ return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
13950
+ ${import_picocolors2.default.gray(o)}` : ""}`;
13677
13951
  }
13678
- hasAb = true;
13679
- ahead = Number(match[1]);
13680
- behind = Number(match[2]);
13681
- continue;
13682
- }
13683
- if (!line.startsWith("# ")) {
13684
- dirty = true;
13952
+ case "error": {
13953
+ const s = this.error.split(`
13954
+ `).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
13955
+ `);
13956
+ return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
13957
+ ${import_picocolors2.default.yellow(o)} `)}
13958
+ ${s}
13959
+ `;
13960
+ }
13961
+ default:
13962
+ return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
13963
+ ${import_picocolors2.default.cyan(o)} `)}
13964
+ ${import_picocolors2.default.cyan(d2)}
13965
+ `;
13685
13966
  }
13686
- }
13687
- return {
13688
- ahead,
13689
- behind,
13690
- hasUpstream,
13691
- upstreamGone: hasUpstream && !hasAb,
13692
- status: dirty ? "dirty" : "clean"
13693
- };
13694
- }
13695
- function hasExitCode(error, code) {
13696
- return error instanceof Error && "code" in error && error.code === code;
13697
- }
13967
+ } }).prompt();
13968
+ };
13969
+ var Ie = (t = "") => {
13970
+ process.stdout.write(`${import_picocolors2.default.gray(ue)} ${t}
13971
+ `);
13972
+ };
13973
+ var Se = (t = "") => {
13974
+ process.stdout.write(`${import_picocolors2.default.gray(o)}
13975
+ ${import_picocolors2.default.gray(d2)} ${t}
13976
+
13977
+ `);
13978
+ };
13979
+ var J2 = `${import_picocolors2.default.gray(o)} `;
13698
13980
 
13699
13981
  // src/headless.ts
13700
13982
  function isHeadless() {
@@ -13808,113 +14090,6 @@ function formatRelativeAge(timestampSeconds) {
13808
14090
  // src/worktree-management.ts
13809
14091
  import { execFile as execFile2 } from "node:child_process";
13810
14092
  import { promisify as promisify3 } from "node:util";
13811
-
13812
- // src/repo.ts
13813
- import { basename, dirname as dirname2, isAbsolute, join as join2, resolve as resolve2 } from "node:path";
13814
- import { homedir as homedir2 } from "node:os";
13815
- async function detectRepository(cwd) {
13816
- const currentRoot = await runGit(cwd, ["rev-parse", "--show-toplevel"]);
13817
- const rawCommonDir = await runGit(cwd, ["rev-parse", "--git-common-dir"]);
13818
- const gitCommonDir = isAbsolute(rawCommonDir) ? rawCommonDir : resolve2(currentRoot, rawCommonDir);
13819
- const repoRoot = dirname2(gitCommonDir);
13820
- return {
13821
- currentRoot,
13822
- gitCommonDir,
13823
- isWorktree: currentRoot !== repoRoot,
13824
- repoName: basename(repoRoot),
13825
- repoRoot
13826
- };
13827
- }
13828
- function resolveWorktreePath(repoRoot, branch, basePath) {
13829
- const segments = branch.split("/").filter(Boolean);
13830
- if (segments.length === 0) {
13831
- throw new Error("Branch name must not be empty.");
13832
- }
13833
- if (segments.some((segment) => segment === "." || segment === "..")) {
13834
- throw new Error(`Branch name '${branch}' contains an invalid path segment.`);
13835
- }
13836
- const base = basePath ? expandTildeInPath(basePath) : join2(dirname2(repoRoot), "worktrees", basename(repoRoot));
13837
- return join2(base, ...segments);
13838
- }
13839
- function validateBranchName(name) {
13840
- if (name.length === 0) {
13841
- return "Branch name must not be empty.";
13842
- }
13843
- if (/[\x00-\x1f\x7f ~^:?*[\\\s]/.test(name)) {
13844
- return `Branch name '${name}' contains an invalid character.`;
13845
- }
13846
- if (name.startsWith("-")) {
13847
- return `Branch name '${name}' must not start with a dash.`;
13848
- }
13849
- if (name.startsWith("/") || name.endsWith("/") || name.includes("//")) {
13850
- return `Branch name '${name}' has invalid slash placement.`;
13851
- }
13852
- if (name.includes("..")) {
13853
- return `Branch name '${name}' must not contain '..'.`;
13854
- }
13855
- if (name.endsWith(".")) {
13856
- return `Branch name '${name}' must not end with '.'.`;
13857
- }
13858
- if (name.includes("@{")) {
13859
- return `Branch name '${name}' must not contain '@{'.`;
13860
- }
13861
- if (name === "@") {
13862
- return "Branch name cannot be '@'.";
13863
- }
13864
- for (const segment of name.split("/")) {
13865
- if (segment.startsWith(".")) {
13866
- return `Branch name '${name}' contains a path component starting with '.'.`;
13867
- }
13868
- if (segment.endsWith(".lock")) {
13869
- return `Branch name '${name}' contains a path component ending with '.lock'.`;
13870
- }
13871
- }
13872
- return null;
13873
- }
13874
- function expandTildeInPath(p2) {
13875
- if (p2 === "~") return homedir2();
13876
- if (p2.startsWith("~/")) return join2(homedir2(), p2.slice(2));
13877
- return p2;
13878
- }
13879
- async function listWorktrees(cwd) {
13880
- const [output, currentRoot] = await Promise.all([
13881
- runGit(cwd, ["worktree", "list", "--porcelain"]),
13882
- runGit(cwd, ["rev-parse", "--show-toplevel"])
13883
- ]);
13884
- const entries = output.split("\n\n").filter(Boolean);
13885
- return entries.map((entry) => {
13886
- const path9 = findPorcelainValue(entry, "worktree");
13887
- const branchRef = findOptionalPorcelainValue(entry, "branch");
13888
- return {
13889
- branch: branchRef ? branchRef.replace("refs/heads/", "") : null,
13890
- isCurrent: path9 === currentRoot,
13891
- path: path9
13892
- };
13893
- });
13894
- }
13895
- function sortByCurrentFirst(worktrees) {
13896
- return [...worktrees].sort((a, b3) => {
13897
- if (a.isCurrent && !b3.isCurrent) return -1;
13898
- if (!a.isCurrent && b3.isCurrent) return 1;
13899
- return 0;
13900
- });
13901
- }
13902
- function findPorcelainValue(block, key) {
13903
- const value = findOptionalPorcelainValue(block, key);
13904
- if (!value) {
13905
- throw new Error(`Missing '${key}' in git worktree output.`);
13906
- }
13907
- return value;
13908
- }
13909
- function findOptionalPorcelainValue(block, key) {
13910
- const line = block.split("\n").find((candidate) => candidate.startsWith(`${key} `));
13911
- if (!line) {
13912
- return null;
13913
- }
13914
- return line.slice(key.length + 1);
13915
- }
13916
-
13917
- // src/worktree-management.ts
13918
14093
  var execFileAsync2 = promisify3(execFile2);
13919
14094
  var GIT_ENV = { ...process.env, LC_ALL: "C" };
13920
14095
  async function loadLinkedWorktrees(cwd) {
@@ -14234,6 +14409,22 @@ async function defaultConfirmRemoval(worktrees) {
14234
14409
  return !pD(choice) && choice;
14235
14410
  }
14236
14411
 
14412
+ // src/history-command.ts
14413
+ async function runHistoryCommand(options) {
14414
+ const history = await loadHistory(options.home);
14415
+ if (options.json) {
14416
+ options.stdout(`${JSON.stringify(history, null, 2)}
14417
+ `);
14418
+ return 0;
14419
+ }
14420
+ if (history.length === 0) {
14421
+ options.stdout("No navigation history.\n");
14422
+ return 0;
14423
+ }
14424
+ options.stdout(formatHistoryList(history, options.cwd));
14425
+ return 0;
14426
+ }
14427
+
14237
14428
  // src/shell-completion.ts
14238
14429
  var TOP_LEVEL_COMMANDS = [
14239
14430
  { name: "new", description: "create a new branch or detached linked worktree" },
@@ -14605,71 +14796,7 @@ function writeJson(stdout, value) {
14605
14796
  }
14606
14797
 
14607
14798
  // src/go.ts
14608
- import { basename as basename2 } from "node:path";
14609
-
14610
- // src/hooks.ts
14611
- import { spawn as spawn2 } from "node:child_process";
14612
- async function runHook(hookCmd, cwd, context, stderr) {
14613
- if (!hookCmd) return;
14614
- const interpolated = interpolate(hookCmd, context);
14615
- await new Promise((resolve3) => {
14616
- const child = spawn2(interpolated, {
14617
- cwd,
14618
- shell: true,
14619
- stdio: ["ignore", "inherit", "pipe"],
14620
- env: {
14621
- ...process.env,
14622
- GJI_BRANCH: context.branch ?? "",
14623
- GJI_PATH: context.path,
14624
- GJI_REPO: context.repo
14625
- }
14626
- });
14627
- child.stderr.on("data", (chunk) => {
14628
- stderr(chunk.toString());
14629
- });
14630
- child.on("close", (code) => {
14631
- if (code !== 0) {
14632
- stderr(`gji: hook exited with code ${code}: ${interpolated}
14633
- `);
14634
- }
14635
- resolve3();
14636
- });
14637
- child.on("error", (err) => {
14638
- stderr(`gji: hook failed to start: ${err.message}
14639
- `);
14640
- resolve3();
14641
- });
14642
- });
14643
- }
14644
- function interpolate(template, context) {
14645
- return template.replace(/\{\{branch\}\}/g, context.branch ?? "").replace(/\{\{path\}\}/g, context.path).replace(/\{\{repo\}\}/g, context.repo);
14646
- }
14647
- function extractHooks(config) {
14648
- const raw = config.hooks;
14649
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
14650
- return {};
14651
- }
14652
- const hooks = raw;
14653
- return {
14654
- afterCreate: typeof hooks.afterCreate === "string" ? hooks.afterCreate : void 0,
14655
- afterEnter: typeof hooks.afterEnter === "string" ? hooks.afterEnter : void 0,
14656
- beforeRemove: typeof hooks.beforeRemove === "string" ? hooks.beforeRemove : void 0
14657
- };
14658
- }
14659
-
14660
- // src/shell-handoff.ts
14661
- import { writeFile as writeFile2 } from "node:fs/promises";
14662
- async function writeShellOutput(envVar, value, stdout) {
14663
- const output = `${value}
14664
- `;
14665
- if (process.env[envVar]) {
14666
- await writeFile2(process.env[envVar], output, "utf8");
14667
- return;
14668
- }
14669
- stdout(output);
14670
- }
14671
-
14672
- // src/go.ts
14799
+ import { basename as basename3 } from "node:path";
14673
14800
  var GO_OUTPUT_FILE_ENV = "GJI_GO_OUTPUT_FILE";
14674
14801
  function createGoCommand(dependencies = {}) {
14675
14802
  const prompt = dependencies.promptForWorktree ?? promptForWorktree;
@@ -14701,9 +14828,10 @@ function createGoCommand(dependencies = {}) {
14701
14828
  await runHook(
14702
14829
  hooks.afterEnter,
14703
14830
  resolvedPath,
14704
- { branch: chosenWorktree?.branch ?? void 0, path: resolvedPath, repo: basename2(repository.repoRoot) },
14831
+ { branch: chosenWorktree?.branch ?? void 0, path: resolvedPath, repo: basename3(repository.repoRoot) },
14705
14832
  options.stderr
14706
14833
  );
14834
+ appendHistory(resolvedPath, chosenWorktree?.branch ?? null).catch(() => void 0);
14707
14835
  await writeShellOutput(GO_OUTPUT_FILE_ENV, resolvedPath, options.stdout);
14708
14836
  return 0;
14709
14837
  };
@@ -14742,9 +14870,9 @@ function formatUpstreamHint(branch, health) {
14742
14870
  }
14743
14871
 
14744
14872
  // src/init.ts
14745
- import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
14746
- import { homedir as homedir3 } from "node:os";
14747
- import { dirname as dirname3, join as join3 } from "node:path";
14873
+ import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
14874
+ import { homedir as homedir4 } from "node:os";
14875
+ import { dirname as dirname4, join as join4 } from "node:path";
14748
14876
  var START_MARKER = "# >>> gji init >>>";
14749
14877
  var END_MARKER = "# <<< gji init <<<";
14750
14878
  var SHELL_WRAPPED_COMMANDS = [
@@ -14762,6 +14890,13 @@ var SHELL_WRAPPED_COMMANDS = [
14762
14890
  names: ["pr"],
14763
14891
  tempPrefix: "gji-pr"
14764
14892
  },
14893
+ {
14894
+ bypassOption: "--print",
14895
+ commandName: "back",
14896
+ envVar: "GJI_BACK_OUTPUT_FILE",
14897
+ names: ["back"],
14898
+ tempPrefix: "gji-back"
14899
+ },
14765
14900
  {
14766
14901
  bypassOption: "--print",
14767
14902
  commandName: "go",
@@ -14786,7 +14921,7 @@ var SHELL_WRAPPED_COMMANDS = [
14786
14921
  ];
14787
14922
  async function runInitCommand(options) {
14788
14923
  const shell = resolveSupportedShell(options.shell, process.env.SHELL);
14789
- const home = options.home ?? homedir3();
14924
+ const home = options.home ?? homedir4();
14790
14925
  if (!shell) {
14791
14926
  options.stderr?.(
14792
14927
  "Unable to detect a supported shell. Specify one explicitly: bash, fish, or zsh.\n"
@@ -14799,10 +14934,10 @@ async function runInitCommand(options) {
14799
14934
  return 0;
14800
14935
  }
14801
14936
  const rcPath = resolveShellConfigPath(shell, home);
14802
- await mkdir2(dirname3(rcPath), { recursive: true });
14937
+ await mkdir3(dirname4(rcPath), { recursive: true });
14803
14938
  const current = await readExistingConfig(rcPath);
14804
14939
  const next = upsertShellIntegration(current, script);
14805
- await writeFile3(rcPath, next, "utf8");
14940
+ await writeFile4(rcPath, next, "utf8");
14806
14941
  options.stdout(`${rcPath}
14807
14942
  `);
14808
14943
  const { config: globalConfig } = await loadGlobalConfig(home);
@@ -14887,16 +15022,16 @@ async function saveWizardConfig(result, cwd, home) {
14887
15022
  function resolveShellConfigPath(shell, home) {
14888
15023
  switch (shell) {
14889
15024
  case "bash":
14890
- return join3(home, ".bashrc");
15025
+ return join4(home, ".bashrc");
14891
15026
  case "fish":
14892
- return join3(home, ".config", "fish", "config.fish");
15027
+ return join4(home, ".config", "fish", "config.fish");
14893
15028
  case "zsh":
14894
- return join3(home, ".zshrc");
15029
+ return join4(home, ".zshrc");
14895
15030
  }
14896
15031
  }
14897
15032
  async function readExistingConfig(path9) {
14898
15033
  try {
14899
- return await readFile2(path9, "utf8");
15034
+ return await readFile3(path9, "utf8");
14900
15035
  } catch (error) {
14901
15036
  if (isMissingFileError2(error)) {
14902
15037
  return "";
@@ -15108,14 +15243,14 @@ function sortWorktrees(worktrees) {
15108
15243
  }
15109
15244
 
15110
15245
  // src/new.ts
15111
- import { mkdir as mkdir4 } from "node:fs/promises";
15112
- import { basename as basename3, dirname as dirname5 } from "node:path";
15246
+ import { mkdir as mkdir5 } from "node:fs/promises";
15247
+ import { basename as basename4, dirname as dirname6 } from "node:path";
15113
15248
  import { execFile as execFile3 } from "node:child_process";
15114
15249
  import { promisify as promisify4 } from "node:util";
15115
15250
 
15116
15251
  // src/file-sync.ts
15117
- import { copyFile, mkdir as mkdir3, stat } from "node:fs/promises";
15118
- import { dirname as dirname4, isAbsolute as isAbsolute2, join as join4, normalize } from "node:path";
15252
+ import { copyFile, mkdir as mkdir4, stat } from "node:fs/promises";
15253
+ import { dirname as dirname5, isAbsolute as isAbsolute2, join as join5, normalize } from "node:path";
15119
15254
  async function syncFiles(mainRoot, targetPath, patterns) {
15120
15255
  for (const pattern of patterns) {
15121
15256
  if (isAbsolute2(pattern)) {
@@ -15125,8 +15260,8 @@ async function syncFiles(mainRoot, targetPath, patterns) {
15125
15260
  if (normalized.startsWith("..")) {
15126
15261
  throw new Error(`syncFiles: pattern must not contain '..' segments, got: ${pattern}`);
15127
15262
  }
15128
- const sourcePath = join4(mainRoot, normalized);
15129
- const destPath = join4(targetPath, normalized);
15263
+ const sourcePath = join5(mainRoot, normalized);
15264
+ const destPath = join5(targetPath, normalized);
15130
15265
  const sourceExists = await fileExists(sourcePath);
15131
15266
  if (!sourceExists) {
15132
15267
  continue;
@@ -15135,7 +15270,7 @@ async function syncFiles(mainRoot, targetPath, patterns) {
15135
15270
  if (destExists) {
15136
15271
  continue;
15137
15272
  }
15138
- await mkdir3(dirname4(destPath), { recursive: true });
15273
+ await mkdir4(dirname5(destPath), { recursive: true });
15139
15274
  await copyFile(sourcePath, destPath);
15140
15275
  }
15141
15276
  }
@@ -15158,8 +15293,8 @@ function isNotFoundError(error) {
15158
15293
  import { spawn as spawn3 } from "node:child_process";
15159
15294
 
15160
15295
  // src/package-manager.ts
15161
- import { access, readdir } from "node:fs/promises";
15162
- import { join as join5 } from "node:path";
15296
+ import { access as access2, readdir } from "node:fs/promises";
15297
+ import { join as join6 } from "node:path";
15163
15298
  var ENTRIES = [
15164
15299
  // JavaScript / TypeScript
15165
15300
  { name: "pnpm", signals: ["pnpm-lock.yaml"], command: "pnpm install" },
@@ -15238,7 +15373,7 @@ async function detectPackageManager(repoRoot) {
15238
15373
  async function matchesExact(repoRoot, signals) {
15239
15374
  for (const signal of signals) {
15240
15375
  try {
15241
- await access(join5(repoRoot, signal));
15376
+ await access2(join6(repoRoot, signal));
15242
15377
  return true;
15243
15378
  } catch {
15244
15379
  }
@@ -15323,7 +15458,7 @@ async function maybeRunInstallPrompt(worktreePath, repoRoot, config, stderr, dep
15323
15458
  }
15324
15459
  }
15325
15460
  async function defaultRunInstallCommand(command, cwd, stderr) {
15326
- await new Promise((resolve3, reject) => {
15461
+ await new Promise((resolve4, reject) => {
15327
15462
  const child = spawn3(command, { cwd, shell: true, stdio: ["ignore", "inherit", "pipe"] });
15328
15463
  child.stderr.on("data", (chunk) => {
15329
15464
  stderr(chunk.toString());
@@ -15332,7 +15467,7 @@ async function defaultRunInstallCommand(command, cwd, stderr) {
15332
15467
  if (code !== 0) {
15333
15468
  reject(new Error(`exited with code ${code}`));
15334
15469
  } else {
15335
- resolve3();
15470
+ resolve4();
15336
15471
  }
15337
15472
  });
15338
15473
  child.on("error", (err) => {
@@ -15372,11 +15507,11 @@ function isPlainObject2(value) {
15372
15507
  }
15373
15508
 
15374
15509
  // src/conflict.ts
15375
- import { access as access2 } from "node:fs/promises";
15510
+ import { access as access3 } from "node:fs/promises";
15376
15511
  import { constants } from "node:fs";
15377
15512
  async function pathExists(path9) {
15378
15513
  try {
15379
- await access2(path9, constants.F_OK);
15514
+ await access3(path9, constants.F_OK);
15380
15515
  return true;
15381
15516
  } catch {
15382
15517
  return false;
@@ -15486,6 +15621,7 @@ function createNewCommand(dependencies = {}) {
15486
15621
  } else {
15487
15622
  const choice = await prompt(worktreePath);
15488
15623
  if (choice === "reuse") {
15624
+ appendHistory(worktreePath, worktreeName).catch(() => void 0);
15489
15625
  await writeOutput(worktreePath, options.stdout);
15490
15626
  return 0;
15491
15627
  }
@@ -15504,7 +15640,7 @@ function createNewCommand(dependencies = {}) {
15504
15640
  }
15505
15641
  return 0;
15506
15642
  }
15507
- await mkdir4(dirname5(worktreePath), { recursive: true });
15643
+ await mkdir5(dirname6(worktreePath), { recursive: true });
15508
15644
  const gitArgs = options.detached ? ["worktree", "add", "--detach", worktreePath] : await localBranchExists(repository.repoRoot, worktreeName) ? ["worktree", "add", worktreePath, worktreeName] : ["worktree", "add", "-b", worktreeName, worktreePath];
15509
15645
  await execFileAsync3("git", gitArgs, { cwd: repository.repoRoot });
15510
15646
  const syncPatterns = Array.isArray(config.syncFiles) ? config.syncFiles.filter((p2) => typeof p2 === "string") : [];
@@ -15521,13 +15657,14 @@ function createNewCommand(dependencies = {}) {
15521
15657
  await runHook(
15522
15658
  hooks.afterCreate,
15523
15659
  worktreePath,
15524
- { branch: worktreeName, path: worktreePath, repo: basename3(repository.repoRoot) },
15660
+ { branch: worktreeName, path: worktreePath, repo: basename4(repository.repoRoot) },
15525
15661
  options.stderr
15526
15662
  );
15527
15663
  if (options.json) {
15528
15664
  options.stdout(`${JSON.stringify({ branch: worktreeName, path: worktreePath }, null, 2)}
15529
15665
  `);
15530
15666
  } else {
15667
+ await appendHistory(worktreePath, worktreeName);
15531
15668
  await writeOutput(worktreePath, options.stdout);
15532
15669
  }
15533
15670
  return 0;
@@ -15638,8 +15775,8 @@ function toExecMessage(error) {
15638
15775
  }
15639
15776
 
15640
15777
  // src/pr.ts
15641
- import { mkdir as mkdir5 } from "node:fs/promises";
15642
- import { basename as basename4, dirname as dirname6 } from "node:path";
15778
+ import { mkdir as mkdir6 } from "node:fs/promises";
15779
+ import { basename as basename5, dirname as dirname7 } from "node:path";
15643
15780
  import { execFile as execFile4 } from "node:child_process";
15644
15781
  import { promisify as promisify5 } from "node:util";
15645
15782
  var execFileAsync4 = promisify5(execFile4);
@@ -15690,6 +15827,7 @@ function createPrCommand(dependencies = {}) {
15690
15827
  }
15691
15828
  const choice = await prompt(worktreePath);
15692
15829
  if (choice === "reuse") {
15830
+ appendHistory(worktreePath, branchName).catch(() => void 0);
15693
15831
  await writeOutput2(worktreePath, options.stdout);
15694
15832
  return 0;
15695
15833
  }
@@ -15722,7 +15860,7 @@ function createPrCommand(dependencies = {}) {
15722
15860
  }
15723
15861
  return 1;
15724
15862
  }
15725
- await mkdir5(dirname6(worktreePath), { recursive: true });
15863
+ await mkdir6(dirname7(worktreePath), { recursive: true });
15726
15864
  const branchAlreadyExists = await localBranchExists2(repository.repoRoot, branchName);
15727
15865
  const worktreeArgs = branchAlreadyExists ? ["worktree", "add", worktreePath, branchName] : ["worktree", "add", "-b", branchName, worktreePath, remoteRef];
15728
15866
  await execFileAsync4("git", worktreeArgs, { cwd: repository.repoRoot });
@@ -15740,13 +15878,14 @@ function createPrCommand(dependencies = {}) {
15740
15878
  await runHook(
15741
15879
  hooks.afterCreate,
15742
15880
  worktreePath,
15743
- { branch: branchName, path: worktreePath, repo: basename4(repository.repoRoot) },
15881
+ { branch: branchName, path: worktreePath, repo: basename5(repository.repoRoot) },
15744
15882
  options.stderr
15745
15883
  );
15746
15884
  if (options.json) {
15747
15885
  options.stdout(`${JSON.stringify({ branch: branchName, path: worktreePath }, null, 2)}
15748
15886
  `);
15749
15887
  } else {
15888
+ await appendHistory(worktreePath, branchName);
15750
15889
  await writeOutput2(worktreePath, options.stdout);
15751
15890
  }
15752
15891
  return 0;
@@ -15812,7 +15951,7 @@ async function writeOutput2(worktreePath, stdout) {
15812
15951
  }
15813
15952
 
15814
15953
  // src/remove.ts
15815
- import { basename as basename5 } from "node:path";
15954
+ import { basename as basename6 } from "node:path";
15816
15955
  var REMOVE_OUTPUT_FILE_ENV = "GJI_REMOVE_OUTPUT_FILE";
15817
15956
  function createRemoveCommand(dependencies = {}) {
15818
15957
  const promptForWorktree2 = dependencies.promptForWorktree ?? defaultPromptForWorktree;
@@ -15877,7 +16016,7 @@ function createRemoveCommand(dependencies = {}) {
15877
16016
  await runHook(
15878
16017
  hooks.beforeRemove,
15879
16018
  worktree.path,
15880
- { branch: worktree.branch ?? void 0, path: worktree.path, repo: basename5(repository.repoRoot) },
16019
+ { branch: worktree.branch ?? void 0, path: worktree.path, repo: basename6(repository.repoRoot) },
15881
16020
  options.stderr
15882
16021
  );
15883
16022
  try {
@@ -16264,6 +16403,8 @@ function registerCommands(program2) {
16264
16403
  program2.command("init [shell]").description("print or install shell integration").option("--write", "write the integration to the shell config file").action(notImplemented("init"));
16265
16404
  program2.command("completion [shell]").description("print shell completion definitions").action(notImplemented("completion"));
16266
16405
  program2.command("pr <ref>").description("fetch a pull request by number, #number, or URL into a linked worktree").option("--dry-run", "show what would be created without executing any git commands or writing files").option("--json", "emit JSON on success or error instead of human-readable output").action(notImplemented("pr"));
16406
+ program2.command("back [n]").description("navigate to the previously visited worktree, optionally N steps back").option("--print", "print the resolved worktree path explicitly").action(notImplemented("back"));
16407
+ program2.command("history").description("show navigation history").option("--json", "print history as JSON").action(notImplemented("history"));
16267
16408
  program2.command("go [branch]").description("print or select a worktree path").option("--print", "print the resolved worktree path explicitly").action(notImplemented("go"));
16268
16409
  program2.command("root").description("print the main repository root path").option("--print", "print the resolved repository root path explicitly").action(notImplemented("root"));
16269
16410
  program2.command("status").description("summarize repository and worktree health").option("--json", "print repository and worktree health as JSON").action(notImplemented("status"));
@@ -16312,6 +16453,34 @@ function attachCommandActions(program2, options) {
16312
16453
  throw commanderExit(exitCode);
16313
16454
  }
16314
16455
  });
16456
+ program2.commands.find((command) => command.name() === "back")?.action(async (n, commandOptions) => {
16457
+ if (n !== void 0 && !/^\d+$/.test(n)) {
16458
+ options.stderr(`gji back: invalid step count: ${n}
16459
+ `);
16460
+ throw commanderExit(1);
16461
+ }
16462
+ const steps = n !== void 0 ? parseInt(n, 10) : void 0;
16463
+ const exitCode = await runBackCommand({
16464
+ cwd: options.cwd,
16465
+ n: steps,
16466
+ print: commandOptions.print,
16467
+ stderr: options.stderr,
16468
+ stdout: options.stdout
16469
+ });
16470
+ if (exitCode !== 0) {
16471
+ throw commanderExit(exitCode);
16472
+ }
16473
+ });
16474
+ program2.commands.find((command) => command.name() === "history")?.action(async (commandOptions) => {
16475
+ const exitCode = await runHistoryCommand({
16476
+ cwd: options.cwd,
16477
+ json: commandOptions.json,
16478
+ stdout: options.stdout
16479
+ });
16480
+ if (exitCode !== 0) {
16481
+ throw commanderExit(exitCode);
16482
+ }
16483
+ });
16315
16484
  program2.commands.find((command) => command.name() === "go")?.action(async (branch, commandOptions) => {
16316
16485
  const exitCode = await runGoCommand({
16317
16486
  branch,
@@ -16488,7 +16657,7 @@ async function main() {
16488
16657
  }
16489
16658
  async function warnIfMissingShellIntegration() {
16490
16659
  try {
16491
- const { config } = await loadGlobalConfig(homedir4());
16660
+ const { config } = await loadGlobalConfig(homedir5());
16492
16661
  if (!config.shellIntegration) {
16493
16662
  const shellBin = (process.env.SHELL ?? "").split("/").at(-1);
16494
16663
  const shellArg = shellBin && ["bash", "zsh", "fish"].includes(shellBin) ? ` ${shellBin}` : "";