happy-imou-cloud 2.1.21 → 2.1.22

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.
Files changed (26) hide show
  1. package/dist/{BaseReasoningProcessor-DxFwO2z9.cjs → BaseReasoningProcessor-BVdXoFXc.cjs} +2 -2
  2. package/dist/{BaseReasoningProcessor-DdPnQSmQ.mjs → BaseReasoningProcessor-BYNLDM-T.mjs} +2 -2
  3. package/dist/{ProviderSelectionHandler-B5Aq5gA_.cjs → ProviderSelectionHandler-DDzNcWPJ.cjs} +2 -2
  4. package/dist/{ProviderSelectionHandler-DQITIqZK.mjs → ProviderSelectionHandler-DgINCAMh.mjs} +2 -2
  5. package/dist/{api-8xtJZeXZ.cjs → api-BXGRJ5Kn.cjs} +75 -15
  6. package/dist/{api-DB30ctmX.mjs → api-bhF1J82q.mjs} +73 -16
  7. package/dist/{command-79M8Bz4I.cjs → command-Byj1OLb9.cjs} +2 -2
  8. package/dist/{command-C6injNJE.mjs → command-CyUpFVkQ.mjs} +2 -2
  9. package/dist/{index-D4A092LJ.cjs → index-BNTRi6Uv.cjs} +374 -57
  10. package/dist/{index-krVv4CWK.mjs → index-CEhnCQim.mjs} +372 -55
  11. package/dist/index.cjs +2 -2
  12. package/dist/index.mjs +2 -2
  13. package/dist/lib.cjs +1 -1
  14. package/dist/lib.d.cts +132 -72
  15. package/dist/lib.d.mts +132 -72
  16. package/dist/lib.mjs +1 -1
  17. package/dist/{registerKillSessionHandler-beu2g-Qo.mjs → registerKillSessionHandler-BtPo6LkG.mjs} +2 -2
  18. package/dist/{registerKillSessionHandler-Cl_er9rg.cjs → registerKillSessionHandler-CuP57vY0.cjs} +2 -2
  19. package/dist/{runClaude-nzLh-orP.mjs → runClaude-CMKm1bBe.mjs} +4 -4
  20. package/dist/{runClaude-DmXinUiz.cjs → runClaude-CqJgxqjW.cjs} +4 -4
  21. package/dist/{runCodex-C-Pjpbxn.mjs → runCodex-BkfujuLR.mjs} +9 -7
  22. package/dist/{runCodex-CoqsQ-cb.cjs → runCodex-DIaZ1wGI.cjs} +9 -7
  23. package/dist/{runGemini-CIVm6NWC.mjs → runGemini-DcN0Nb3f.mjs} +4 -4
  24. package/dist/{runGemini-BC_5rNMt.cjs → runGemini-U4GRLlSn.cjs} +4 -4
  25. package/package.json +1 -1
  26. package/scripts/tooling-utils.mjs +167 -167
@@ -1,6 +1,6 @@
1
- import { p as preserveSessionRuntimeMetadata, l as logger, b as connectionState, A as ApiClient } from './api-DB30ctmX.mjs';
2
- import { B as BasePermissionHandler, h as hashObject, d as MessageBuffer, C as ConversationHistory$1, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, c as registerKillSessionHandler, l as launchRuntimeHandleWithFactoryResult, j as inferToolResultError, k as forwardAgentMessageToProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-beu2g-Qo.mjs';
3
- import { f as formatDisplayMessage, v as validateCodexAcpSpawn, h as createCodexBackend, t as truncateDisplayMessage, b as closeProviderSession, e as stopCaffeinate, i as readManagedSessionTag, j as resolveManagedSessionTag } from './index-krVv4CWK.mjs';
1
+ import { p as preserveSessionRuntimeMetadata, l as logger, b as connectionState, A as ApiClient } from './api-bhF1J82q.mjs';
2
+ import { B as BasePermissionHandler, h as hashObject, d as MessageBuffer, C as ConversationHistory$1, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, c as registerKillSessionHandler, l as launchRuntimeHandleWithFactoryResult, j as inferToolResultError, k as forwardAgentMessageToProviderSession, e as ensureManagedProviderMachine, M as MissingMachineIdError, b as MessageQueue2, r as resolveHappyOrgQueuedTurn, s as syncControlledByUserState } from './registerKillSessionHandler-BtPo6LkG.mjs';
3
+ import { f as formatDisplayMessage, v as validateCodexAcpSpawn, h as createCodexBackend, t as truncateDisplayMessage, b as closeProviderSession, e as stopCaffeinate, i as readManagedSessionTag, j as resolveManagedSessionTag } from './index-CEhnCQim.mjs';
4
4
  import 'cross-spawn';
5
5
  import '@agentclientprotocol/sdk';
6
6
  import { randomUUID } from 'node:crypto';
@@ -24,8 +24,8 @@ import 'tweetnacl';
24
24
  import 'open';
25
25
  import React, { useState, useRef, useEffect, useCallback } from 'react';
26
26
  import { useStdout, useInput, Box, Text, render } from 'ink';
27
- import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-DQITIqZK.mjs';
28
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-DdPnQSmQ.mjs';
27
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-DgINCAMh.mjs';
28
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-BYNLDM-T.mjs';
29
29
  import 'zod';
30
30
  import 'socket.io-client';
31
31
  import 'expo-server-sdk';
@@ -1246,8 +1246,10 @@ function resolveIncomingCodexPermissionMode(opts) {
1246
1246
  };
1247
1247
  }
1248
1248
  async function runCodex(opts) {
1249
- const managedSessionTag = readManagedSessionTag();
1250
- const sessionTag = managedSessionTag ?? resolveManagedSessionTag();
1249
+ const managedSessionTag = opts.startedBy === "daemon" ? readManagedSessionTag() : null;
1250
+ const sessionTag = managedSessionTag ?? resolveManagedSessionTag(
1251
+ opts.startedBy === "daemon" ? process.env : {}
1252
+ );
1251
1253
  connectionState.setBackend("Codex");
1252
1254
  const requestedStartingMode = opts.startingMode ?? (opts.startedBy === "daemon" ? "remote" : "local");
1253
1255
  const initialPermissionMode = resolveInitialCodexPermissionMode({
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./api-8xtJZeXZ.cjs');
4
- var registerKillSessionHandler = require('./registerKillSessionHandler-Cl_er9rg.cjs');
5
- var index = require('./index-D4A092LJ.cjs');
3
+ var persistence = require('./api-BXGRJ5Kn.cjs');
4
+ var registerKillSessionHandler = require('./registerKillSessionHandler-CuP57vY0.cjs');
5
+ var index = require('./index-BNTRi6Uv.cjs');
6
6
  require('cross-spawn');
7
7
  require('@agentclientprotocol/sdk');
8
8
  var node_crypto = require('node:crypto');
@@ -26,8 +26,8 @@ require('tweetnacl');
26
26
  require('open');
27
27
  var React = require('react');
28
28
  var ink = require('ink');
29
- var ProviderSelectionHandler = require('./ProviderSelectionHandler-B5Aq5gA_.cjs');
30
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-DxFwO2z9.cjs');
29
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-DDzNcWPJ.cjs');
30
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-BVdXoFXc.cjs');
31
31
  require('zod');
32
32
  require('socket.io-client');
33
33
  require('expo-server-sdk');
@@ -1248,8 +1248,10 @@ function resolveIncomingCodexPermissionMode(opts) {
1248
1248
  };
1249
1249
  }
1250
1250
  async function runCodex(opts) {
1251
- const managedSessionTag = index.readManagedSessionTag();
1252
- const sessionTag = managedSessionTag ?? index.resolveManagedSessionTag();
1251
+ const managedSessionTag = opts.startedBy === "daemon" ? index.readManagedSessionTag() : null;
1252
+ const sessionTag = managedSessionTag ?? index.resolveManagedSessionTag(
1253
+ opts.startedBy === "daemon" ? process.env : {}
1254
+ );
1253
1255
  persistence.connectionState.setBackend("Codex");
1254
1256
  const requestedStartingMode = opts.startingMode ?? (opts.startedBy === "daemon" ? "remote" : "local");
1255
1257
  const initialPermissionMode = resolveInitialCodexPermissionMode({
@@ -1,10 +1,10 @@
1
1
  import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { randomUUID } from 'node:crypto';
4
- import { l as logger, b as connectionState, A as ApiClient } from './api-DB30ctmX.mjs';
5
- import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, h as hashObject, c as registerKillSessionHandler, d as MessageBuffer, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, l as launchRuntimeHandleWithFactoryResult, j as inferToolResultError, k as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-beu2g-Qo.mjs';
6
- import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, b as closeProviderSession, s as saveGeminiModelToConfig, d as createGeminiBackend, e as stopCaffeinate } from './index-krVv4CWK.mjs';
7
- import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-DdPnQSmQ.mjs';
4
+ import { l as logger, b as connectionState, A as ApiClient } from './api-bhF1J82q.mjs';
5
+ import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, h as hashObject, c as registerKillSessionHandler, d as MessageBuffer, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, i as finalizeHappyOrgTurnWithBusinessAck, l as launchRuntimeHandleWithFactoryResult, j as inferToolResultError, k as forwardAgentMessageToProviderSession } from './registerKillSessionHandler-BtPo6LkG.mjs';
6
+ import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, b as closeProviderSession, s as saveGeminiModelToConfig, d as createGeminiBackend, e as stopCaffeinate } from './index-CEhnCQim.mjs';
7
+ import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-BYNLDM-T.mjs';
8
8
  import 'cross-spawn';
9
9
  import '@agentclientprotocol/sdk';
10
10
  import 'ps-list';
@@ -3,10 +3,10 @@
3
3
  var ink = require('ink');
4
4
  var React = require('react');
5
5
  var node_crypto = require('node:crypto');
6
- var persistence = require('./api-8xtJZeXZ.cjs');
7
- var registerKillSessionHandler = require('./registerKillSessionHandler-Cl_er9rg.cjs');
8
- var index = require('./index-D4A092LJ.cjs');
9
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-DxFwO2z9.cjs');
6
+ var persistence = require('./api-BXGRJ5Kn.cjs');
7
+ var registerKillSessionHandler = require('./registerKillSessionHandler-CuP57vY0.cjs');
8
+ var index = require('./index-BNTRi6Uv.cjs');
9
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-BVdXoFXc.cjs');
10
10
  require('cross-spawn');
11
11
  require('@agentclientprotocol/sdk');
12
12
  require('ps-list');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-imou-cloud",
3
- "version": "2.1.21",
3
+ "version": "2.1.22",
4
4
  "description": "hicloud - Imou 企业定制版。关键是 happy!移动端远程 AI 编程工具,支持 Claude Code、Codex 和 Gemini CLI",
5
5
  "author": "long.zhu",
6
6
  "license": "MIT",
@@ -1,167 +1,167 @@
1
- import { spawnSync } from 'node:child_process';
2
- import { existsSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
3
- import { dirname, resolve } from 'node:path';
4
-
5
- function getLocalPackageDirs(packageName, packageRoot, workspaceRoot) {
6
- return [
7
- resolve(packageRoot, 'node_modules', packageName),
8
- resolve(workspaceRoot, 'node_modules', packageName),
9
- ];
10
- }
11
-
12
- function getLocalBinPaths(binName, packageRoot, workspaceRoot) {
13
- const suffix = process.platform === 'win32' ? '.cmd' : '';
14
-
15
- return [
16
- resolve(packageRoot, 'node_modules', '.bin', `${binName}${suffix}`),
17
- resolve(workspaceRoot, 'node_modules', '.bin', `${binName}${suffix}`),
18
- ];
19
- }
20
-
21
- function resolveInstalledPackageDir(packageName, packageRoot, workspaceRoot) {
22
- return getLocalPackageDirs(packageName, packageRoot, workspaceRoot)
23
- .find((candidatePath) => existsSync(candidatePath))
24
- ?? null;
25
- }
26
-
27
- export function shouldUseShell(command) {
28
- if (process.platform !== 'win32') {
29
- return false;
30
- }
31
-
32
- return !/\.exe$/i.test(command);
33
- }
34
-
35
- export function resolveTool({
36
- binName,
37
- packageName,
38
- packageRoot,
39
- workspaceRoot,
40
- packageSpecs,
41
- entryCandidates = [],
42
- }) {
43
- for (const packageDir of getLocalPackageDirs(packageName, packageRoot, workspaceRoot)) {
44
- for (const entryCandidate of entryCandidates) {
45
- const entryPath = resolve(packageDir, entryCandidate);
46
-
47
- if (existsSync(entryPath)) {
48
- return {
49
- command: process.execPath,
50
- prefixArgs: [entryPath],
51
- };
52
- }
53
- }
54
- }
55
-
56
- for (const localBinPath of getLocalBinPaths(binName, packageRoot, workspaceRoot)) {
57
- if (existsSync(localBinPath)) {
58
- return {
59
- command: localBinPath,
60
- prefixArgs: [],
61
- };
62
- }
63
- }
64
-
65
- return {
66
- command: 'npx',
67
- prefixArgs: ['-y', ...packageSpecs.flatMap((packageSpec) => ['-p', packageSpec]), binName],
68
- };
69
- }
70
-
71
- export function resolvePackageDirWithNpx({
72
- packageName,
73
- version,
74
- packageRoot,
75
- env = process.env,
76
- spawn = spawnSync,
77
- }) {
78
- const cacheKey = `${packageName.replace(/[@/]/g, '_')}-${version}`;
79
- const installRoot = resolve(packageRoot, 'node_modules', '.tool-cache', cacheKey);
80
- const installPackagePath = resolve(installRoot, 'node_modules', packageName);
81
-
82
- if (existsSync(installPackagePath)) {
83
- return installPackagePath;
84
- }
85
-
86
- mkdirSync(installRoot, { recursive: true });
87
- writeFileSync(
88
- resolve(installRoot, 'package.json'),
89
- JSON.stringify(
90
- {
91
- private: true,
92
- name: `happy-cli-tool-cache-${cacheKey}`,
93
- },
94
- null,
95
- 2
96
- )
97
- );
98
-
99
- const commandArgs = [
100
- 'install',
101
- '--no-save',
102
- '--ignore-scripts',
103
- '--no-package-lock',
104
- '--no-audit',
105
- '--fund=false',
106
- `${packageName}@${version}`,
107
- ];
108
- const result = spawn('npm', commandArgs, {
109
- cwd: installRoot,
110
- encoding: 'utf8',
111
- shell: shouldUseShell('npm'),
112
- env,
113
- });
114
-
115
- if (result.status !== 0) {
116
- const stderr = result.stderr?.trim();
117
- const stdout = result.stdout?.trim();
118
- throw new Error(
119
- stderr && stderr.length > 0
120
- ? stderr
121
- : stdout && stdout.length > 0
122
- ? stdout
123
- : `Failed to install ${packageName}@${version} for local resolution`
124
- );
125
- }
126
-
127
- if (!existsSync(installPackagePath)) {
128
- throw new Error(`Installed package path missing for ${packageName}@${version}`);
129
- }
130
-
131
- return installPackagePath;
132
- }
133
-
134
- export function ensurePackageResolvableFromPackageRoot({
135
- packageName,
136
- version,
137
- packageRoot,
138
- workspaceRoot,
139
- env = process.env,
140
- spawn = spawnSync,
141
- fallbackResolver = resolvePackageDirWithNpx,
142
- }) {
143
- const linkPath = resolve(packageRoot, 'node_modules', packageName);
144
-
145
- if (existsSync(linkPath)) {
146
- return () => {};
147
- }
148
-
149
- const localPackageDir = resolveInstalledPackageDir(packageName, packageRoot, workspaceRoot);
150
- const targetPath = localPackageDir ?? fallbackResolver({
151
- packageName,
152
- version,
153
- packageRoot,
154
- workspaceRoot,
155
- env,
156
- spawn,
157
- });
158
-
159
- mkdirSync(dirname(linkPath), { recursive: true });
160
- symlinkSync(targetPath, linkPath, process.platform === 'win32' ? 'junction' : 'dir');
161
-
162
- return () => {
163
- try {
164
- rmSync(linkPath, { recursive: true, force: true });
165
- } catch {}
166
- };
167
- }
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
3
+ import { dirname, resolve } from 'node:path';
4
+
5
+ function getLocalPackageDirs(packageName, packageRoot, workspaceRoot) {
6
+ return [
7
+ resolve(packageRoot, 'node_modules', packageName),
8
+ resolve(workspaceRoot, 'node_modules', packageName),
9
+ ];
10
+ }
11
+
12
+ function getLocalBinPaths(binName, packageRoot, workspaceRoot) {
13
+ const suffix = process.platform === 'win32' ? '.cmd' : '';
14
+
15
+ return [
16
+ resolve(packageRoot, 'node_modules', '.bin', `${binName}${suffix}`),
17
+ resolve(workspaceRoot, 'node_modules', '.bin', `${binName}${suffix}`),
18
+ ];
19
+ }
20
+
21
+ function resolveInstalledPackageDir(packageName, packageRoot, workspaceRoot) {
22
+ return getLocalPackageDirs(packageName, packageRoot, workspaceRoot)
23
+ .find((candidatePath) => existsSync(candidatePath))
24
+ ?? null;
25
+ }
26
+
27
+ export function shouldUseShell(command) {
28
+ if (process.platform !== 'win32') {
29
+ return false;
30
+ }
31
+
32
+ return !/\.exe$/i.test(command);
33
+ }
34
+
35
+ export function resolveTool({
36
+ binName,
37
+ packageName,
38
+ packageRoot,
39
+ workspaceRoot,
40
+ packageSpecs,
41
+ entryCandidates = [],
42
+ }) {
43
+ for (const packageDir of getLocalPackageDirs(packageName, packageRoot, workspaceRoot)) {
44
+ for (const entryCandidate of entryCandidates) {
45
+ const entryPath = resolve(packageDir, entryCandidate);
46
+
47
+ if (existsSync(entryPath)) {
48
+ return {
49
+ command: process.execPath,
50
+ prefixArgs: [entryPath],
51
+ };
52
+ }
53
+ }
54
+ }
55
+
56
+ for (const localBinPath of getLocalBinPaths(binName, packageRoot, workspaceRoot)) {
57
+ if (existsSync(localBinPath)) {
58
+ return {
59
+ command: localBinPath,
60
+ prefixArgs: [],
61
+ };
62
+ }
63
+ }
64
+
65
+ return {
66
+ command: 'npx',
67
+ prefixArgs: ['-y', ...packageSpecs.flatMap((packageSpec) => ['-p', packageSpec]), binName],
68
+ };
69
+ }
70
+
71
+ export function resolvePackageDirWithNpx({
72
+ packageName,
73
+ version,
74
+ packageRoot,
75
+ env = process.env,
76
+ spawn = spawnSync,
77
+ }) {
78
+ const cacheKey = `${packageName.replace(/[@/]/g, '_')}-${version}`;
79
+ const installRoot = resolve(packageRoot, 'node_modules', '.tool-cache', cacheKey);
80
+ const installPackagePath = resolve(installRoot, 'node_modules', packageName);
81
+
82
+ if (existsSync(installPackagePath)) {
83
+ return installPackagePath;
84
+ }
85
+
86
+ mkdirSync(installRoot, { recursive: true });
87
+ writeFileSync(
88
+ resolve(installRoot, 'package.json'),
89
+ JSON.stringify(
90
+ {
91
+ private: true,
92
+ name: `happy-cli-tool-cache-${cacheKey}`,
93
+ },
94
+ null,
95
+ 2
96
+ )
97
+ );
98
+
99
+ const commandArgs = [
100
+ 'install',
101
+ '--no-save',
102
+ '--ignore-scripts',
103
+ '--no-package-lock',
104
+ '--no-audit',
105
+ '--fund=false',
106
+ `${packageName}@${version}`,
107
+ ];
108
+ const result = spawn('npm', commandArgs, {
109
+ cwd: installRoot,
110
+ encoding: 'utf8',
111
+ shell: shouldUseShell('npm'),
112
+ env,
113
+ });
114
+
115
+ if (result.status !== 0) {
116
+ const stderr = result.stderr?.trim();
117
+ const stdout = result.stdout?.trim();
118
+ throw new Error(
119
+ stderr && stderr.length > 0
120
+ ? stderr
121
+ : stdout && stdout.length > 0
122
+ ? stdout
123
+ : `Failed to install ${packageName}@${version} for local resolution`
124
+ );
125
+ }
126
+
127
+ if (!existsSync(installPackagePath)) {
128
+ throw new Error(`Installed package path missing for ${packageName}@${version}`);
129
+ }
130
+
131
+ return installPackagePath;
132
+ }
133
+
134
+ export function ensurePackageResolvableFromPackageRoot({
135
+ packageName,
136
+ version,
137
+ packageRoot,
138
+ workspaceRoot,
139
+ env = process.env,
140
+ spawn = spawnSync,
141
+ fallbackResolver = resolvePackageDirWithNpx,
142
+ }) {
143
+ const linkPath = resolve(packageRoot, 'node_modules', packageName);
144
+
145
+ if (existsSync(linkPath)) {
146
+ return () => {};
147
+ }
148
+
149
+ const localPackageDir = resolveInstalledPackageDir(packageName, packageRoot, workspaceRoot);
150
+ const targetPath = localPackageDir ?? fallbackResolver({
151
+ packageName,
152
+ version,
153
+ packageRoot,
154
+ workspaceRoot,
155
+ env,
156
+ spawn,
157
+ });
158
+
159
+ mkdirSync(dirname(linkPath), { recursive: true });
160
+ symlinkSync(targetPath, linkPath, process.platform === 'win32' ? 'junction' : 'dir');
161
+
162
+ return () => {
163
+ try {
164
+ rmSync(linkPath, { recursive: true, force: true });
165
+ } catch {}
166
+ };
167
+ }