- copilotๆบ็ ่ฏฆ็ปๅๆ๏ผไธ๏ผไปpackage.json่ฏด่ตท
- copilotๆบ็ ่ฏฆ็ปๅๆ๏ผไบ๏ผactivateๅ ฅๅฃๅๆ
- copilotๆบ็ ่ฏฆ็ปๅๆ๏ผไธ๏ผghostTextๆ ธๅฟ้ป่พ
- ๅฎ็ปๆ่ฑ๏ผcopilotโโ็ป่ๅณๅฎๆ่ดฅ๏ผ
ไปๅนดไบๆ็ๆถๅๆๅไบไธ็ฏๆ็ซ ใ่ฑไบๅคงๅไธชๆ๏ผๆ็ปไบ้ๅๅๆไบGithub Copilotใ๏ผๆ่ฟๅ็ฐcopilot
ๅฐ.map
ๆไปถไนๆไบคไบไธๆฅ๏ผ**sourcemap
**ไธญๅ
ๅซไบๆดไฝๆบ็ ็็ปๆไฟกๆฏๅ้จๅๅ้ไฟกๆฏ๏ผ่ฟๆ ็ไธบๅๆcopilot
ๆบ็ ๅธฆๆฅไบๆๅคง็ไพฟๅฉ๏ผๅ ๆญคๅๆฌกๅๆไธๆณขใ
Sourcemap
ๆฏไธ็ง็จไบๅฐ็ผ่ฏใๆๅ
ๅ็ไปฃ็ ๆ ๅฐๅๅๅงๆบไปฃ็ ็ๆๆฏใๅฎไธป่ฆ็จไบ JavaScript ็ๆบไปฃ็ ๆ ๅฐ๏ผsource map๏ผ๏ผไฝไนๅฏไปฅ็จไบๅ
ถไป็ผ็จ่ฏญ่จใ
ๅจ JavaScript ไธญ๏ผๆบไปฃ็ ๆ ๅฐ๏ผsource map๏ผๆฏไธ็งๆไปถ๏ผๅฎๅ ่ฎธๆต่งๅจๅฐๅ็ผฉใๆททๆทๆ่ฝฌ่ฏๅ็ไปฃ็ ๆ ๅฐๅๅๅงๆบไปฃ็ ใ่ฟๅฏนไบ่ฐ่ฏ้ๅธธๆ็จ๏ผๅ ไธบๅฎๅ ่ฎธๅผๅ่ ๆฅ็ๅ่ฐ่ฏๅๅงๆบไปฃ็ ๏ผ่ไธๆฏ่ขซๅ็ผฉๆๆททๆท็ไปฃ็ ใ
Sourcemap
ๆไปถ้ๅธธไปฅ .map
ๆฉๅฑๅ็ปๅฐพ๏ผๅนถไธๅฏไปฅ้่ฟๆต่งๅจ็ๅผๅ่
ๅทฅๅ
ทๆฅ็ๅไฝฟ็จใ
Sourcemap ๆไปถ็็ปๆไธป่ฆๅ ๆฌไปฅไธๅ ไธช้จๅ๏ผ
- Version: ่ฟๆฏๆบๆ ๅฐๆไปถ็็ๆฌๅทใ็ฎๅ๏ผSourcemap ็็ๆฌๅทไธบ 3ใ
- File: ่ฟๆฏๆบๆ ๅฐๆไปถๆๅฏนๅบ็ๅๅงๆบๆไปถ็ๅ็งฐใ
- SourceRoot: ่ฟๆฏไธไธชๅฏ้็ๅญๆฎต๏ผๅฎๆๅฎไบๆบๆไปถ็ๆ น่ทฏๅพใ
- Sources: ่ฟๆฏไธไธชๅ ๅซๆๆๅๅงๆบๆไปถๅ็ๆฐ็ปใ
- Names: ่ฟๆฏไธไธชๅ ๅซๆๆๅๅงๆบๆไปถไธญไฝฟ็จ็ๅ้ใๅฝๆฐๅ็ฑป็ๅ็งฐ็ๆฐ็ปใ
- Mappings: ่ฟๆฏไธไธชๅญ็ฌฆไธฒ๏ผๅฎๆ่ฟฐไบๆบๆไปถๅ็ๆๆไปถไน้ด็ๆ ๅฐๅ ณ็ณปใ
ไธ้ขๆฏไธไธช็ฎๅ็ Sourcemap ๆไปถ็็คบไพ๏ผ
{
"version": 3,
"file": "out.js",
"sourceRoot": "",
"sources": ["foo.js", "bar.js"],
"names": ["src", "maps", "are", "fun"],
"mappings": "AAAA,SAASA,EAAM,CAAE,GAAG,EAAE,CACC,CAAC"
}
ๅจ่ฟไธช็คบไพไธญ๏ผmappings
ย ๅญๆฎตๆ่ฟฐไบๆบๆไปถๅ็ๆๆไปถไน้ด็ๆ ๅฐๅ
ณ็ณปใ่ฟไธชๅญ็ฌฆไธฒ่ขซๅๆๅคไธช้จๅ๏ผๆฏไธช้จๅๅฏนๅบๆบๆไปถ็ไธ่กใๆฏไธช้จๅ็ฑไธ็ณปๅ็ๆ ๅฐ็ปๆ๏ผๆฏไธชๆ ๅฐๆ่ฟฐไบๆบๆไปถไธญ็ไธไธชๅญ็ฌฆๅจ็ๆๆไปถไธญ็ไฝ็ฝฎใ
Sourcemap
็ย mappings
ย ๅญๆฎตๆฏไธไธชๅญ็ฌฆไธฒ๏ผๅฎๆ่ฟฐไบๆบๆไปถๅ็ๆๆไปถไน้ด็ๆ ๅฐๅ
ณ็ณปใ่ฟไธชๅญ็ฌฆไธฒ่ขซๅๆๅคไธช้จๅ๏ผๆฏไธช้จๅๅฏนๅบๆบๆไปถ็ไธ่กใๆฏไธช้จๅ็ฑไธ็ณปๅ็ๆ ๅฐ็ปๆ๏ผๆฏไธชๆ ๅฐๆ่ฟฐไบๆบๆไปถไธญ็ไธไธชๅญ็ฌฆๅจ็ๆๆไปถไธญ็ไฝ็ฝฎใ
ๆฏไธชๆ ๅฐ็ฑไบไธช้จๅ็ปๆ๏ผ
- ็ๆๆไปถไธญ็ๅๅทใ
- ๆบๆไปถไธญ็่กๅทใ
- ๆบๆไปถไธญ็ๅๅทใ
- ๆบๆไปถไธญ็ๅ็งฐ็ดขๅผใ
- ๆบๆไปถไธญ็ๅ็งฐใ
ๆฏไธช้จๅ้ฝไฝฟ็จ VLQ๏ผVariable-length quantity๏ผ็ผ็ ๏ผ่ฟๆฏไธ็งๅ็ผฉๆฐๅญ็ๆนๆณใVLQ ็ผ็ ไฝฟ็จไธไธชๆๅคไธชๅญ่ๆฅ่กจ็คบไธไธชๆฐๅญ๏ผๆฏไธชๅญ่็ๆ้ซไฝ็จไบๆ็คบๆฏๅฆ่ฟๆๆดๅค็ๅญ่้่ฆ่ฏปๅใ
ไธ้ขๆฏไธไธชย mappings
ย ๅญๆฎต็็คบไพ๏ผ
AAAA,SAASA,EAAM,CAAE,GAAG,EAAE,CACC,CAAC
ๅจ่ฟไธช็คบไพไธญ๏ผAAAA
ย ่กจ็คบ็ๆๆไปถไธญ็็ฌฌไธๅๅฏนๅบๆบๆไปถ็็ฌฌไธ่ก็ฌฌไธๅ๏ผSAASA
ย ่กจ็คบ็ๆๆไปถไธญ็็ฌฌไบๅๅฏนๅบๆบๆไปถ็็ฌฌไบ่ก็ฌฌไบๅ๏ผไปฅๆญค็ฑปๆจใ
Node.js็source-mapๅบๅฏไปฅๅmapๆไปถ็่งฃๆ๏ผ
const sourcemap = require("source-map");
const mapFile = fs.readFileSync("./extension.js.map");
const rawSourceMap = JSON.parse(mapFile.toString());
const nameMap = new Map();
const fileMap = new Map();
await sourcemap.SourceMapConsumer.with(rawSourceMap, null, (consumer) => {
consumer.eachMapping(function (m) {
if (m.name) {
nameMap.set(`${m.generatedLine}:${m.generatedColumn}`, m);
}
if (m.source) {
if (!fileMap.has(m.source)) {
fileMap.set(m.source, {
start: m,
});
} else {
fileMap.set(m.source, {
...fileMap.get(m.source),
end: m,
});
}
}
});
});
ไธ้ขๆไปฌไฝฟ็จsource-map
ๅทฅๅ
ท่งฃๆไบๅ้ๅ็ๆ ๅฐๅ
ณ็ณปไปฅๅๅฏนๅบ็ๆบๆไปถ่ทฏๅพไฟกๆฏ๏ผๅฐ่งฃๆ็็ปๆๅญๅจไบไธคไธชmap
ๅฝไธญ๏ผไพฟไบๆไปฌๅ้ข่ฟ่ก่ฏปๅใ
function updateNodeName(node, name) {
if (node.type === "VariableDeclarator") {
node.id.name = name;
} else if (node.type === "Identifier") {
node.name = name;
} else if (node.type === "CallExpression") {
updateNodeName(node.callee, name);
} else if (node.type === "ArrowFunctionExpression") {
node.params[0].name = name;
} else if (node.type === "ExpressionStatement") {
updateNodeName(node.expression, name);
} else if (node.type === "AssignmentExpression") {
updateNodeName(node.left, name);
} else if (node.type === "MemberExpression") {
updateNodeName(node.object, name);
} else if (node.type === "BinaryExpression") {
updateNodeName(node.left, name);
} else if (node.type === "ConditionalExpression") {
updateNodeName(node.test, name);
} else if (node.type === "LogicalExpression") {
updateNodeName(node.left, name);
} else if (node.type === "SequenceExpression") {
updateNodeName(node.expressions[0], name);
} else if (node.type === "UpdateExpression") {
updateNodeName(node.argument, name);
} else if (node.type === "StringLiteral") {
node.value = name;
} else if (node.type === "AssignmentPattern") {
updateNodeName(node.left, name);
} else if (node.type === "ReturnStatement") {
updateNodeName(node.argument, name);
} else if (node.type === "BlockStatement") {
updateNodeName(node.body[0], name);
} else if (node.type === "UnaryExpression") {
updateNodeName(node.argument, name);
} else if (node.type === "ObjectProperty") {
updateNodeName(node.key, name);
} else if (node.type === "EmptyStatement") {
// ๅฅฝๅๆฏstartๅendๆ ่ฎฐ
// console.log(name);
} else if (node.type === "NumericLiteral") {
node.value = name;
} else if (node.type === "ThisExpression") {
// console.log(name);
} else if (node.type === "ForStatement") {
updateNodeName(node.init, name);
} else if (node.type === "OptionalMemberExpression") {
updateNodeName(node.object, name);
} else if (node.type === "OptionalCallExpression") {
updateNodeName(node.callee, name);
} else if (node.type === "LabeledStatement") {
updateNodeName(node.label, name);
} else if (node.type === "ClassPrivateProperty") {
updateNodeName(node.key, name);
} else if (node.type === "PrivateName") {
updateNodeName(node.id, name);
} else if (node.type === "ClassPrivateMethod") {
updateNodeName(node.key, name);
} else if (node.type === "VariableDeclaration") {
updateNodeName(node.declarations[0], name);
} else if (node.type === "IfStatement") {
updateNodeName(node.test, name);
} else if (node.type === "TryStatement") {
updateNodeName(node.block, name);
} else if (node.type === "SwitchStatement") {
updateNodeName(node.discriminant, name);
} else {
// console.log(node);
}
}
ๆไปฌๅฐ่ฃ
ไบไธไธชupdateNodeName
็ๆนๆณ๏ผ็จไบ้ๅฝๅค็AST
่็นๅฐๅ้ๅฝๅ็ปๆฟๆข๏ผ่ฟ็ๅฎๆฏไธไธชไฝๅๆดปใใใ๏ผ๏ผๅคๆญไบๅ็ฑป่กจ่พพๅผใ่ฏญๅฅใๅญ้ข้็ญ็ญๅบๆฏใ
ๅฏนไบๆไปถ่ทฏๅพๆไปฌๆๆ ทๆ ๅฐ่ฟๅปๅข๏ผ็ฎๅๅทฒ็ฅ็ไฟกๆฏไธป่ฆๆ๏ผ
- ๅฏนๅบๆบไปฃ็ ็
location
- ๅฏนๅบๆบไปฃ็ ็
path
- ๆๆๅ
ทๆๆ ๅฐๅ
ณ็ณป็
map
ไธไธชๆฏ่พ่ช็ถ็ๆณๆณๆฏๅบไบไปฃ็ ็ไฝ็ฝฎๅๅญ็ฌฆๅๅฒใไฝๆฏๆไปฌไธ้ขๅ้ๅฝๅๆฟๆขๅ๏ผ็ๆ็ๆฐ็ไปฃ็ ๆไปถ่กๅทๅๅๅท้ฝๅทฒ็ปๅ็ไบๅๅ๏ผๆ ๆณๆ ๅฐๅฐๅๆฅ็่กๅ๏ผ่ฟๆก่ทฏๅพ้พ่ก็้ใ
ๆไปฅ่ฟๆฏๅจAST
้ๅ้้ขๅค็ๅฎๆฏ่พๅฅฝใ
ๆไปฌไฝฟ็จไธคไธชๅ้ๅๅซ่ฎฐๅฝไธไธๆฌก้ๅ็ๆไปถ่ทฏๅพๅast
็nodes
๏ผ
let lastFile;
let lastNodes = [];
็ถๅๅฏนAST่ฟ่ก้ๅ๏ผๅ ๅค็ๅ้ๅฝๅ๏ผ
traverse(ast, {
enter(p) {
const node = p.node;
const { line, column } = node.loc.start;
// ๅค็ๅ้ๅฝๅ
if (nameMap.has(`${line}:${column}`)) {
const sourceObj = nameMap.get(`${line}:${column}`);
const name = sourceObj.name;
updateNodeName(node, name);
}
},
});
ๅๅค็่ทฏๅพ๏ผ
traverse(ast, {
enter(p) {
const node = p.node;
const { line, column } = node.loc.start;
// ๅค็่ทฏๅพ
for (const [file, m] of fileMap.entries()) {
if (
m.start.generatedLine === line &&
m.start.generatedColumn === column
) {
if (lastFile && lastNodes.length) {
const pp = path.resolve(__dirname, "./prettier/empty", lastFile);
fs.ensureFileSync(pp);
fs.writeFileSync(pp, lastNodes.map(n => generate(n).code).join());
lastNodes = [];
}
lastFile = file;
break;
}
}
if (lastFile) {
lastNodes.push(node);
p.skip();
}
},
});
ๆณจๆ่ฟ้็ๆ่ทฏๆฏๆฏๅฝstart
่ตทๅงๅฏนๅบ็ๆไปถ่ทฏๅพๅ็ๅๅ็ๆถๅ๏ผ็ๆไธไธไธชๆไปถ็ๆบ็ ๏ผ็ถๅๅๅ
ฅๅฐๅฏนๅบ็็ฎๅฝๆไปถๅ
ใ
ๅฆๅคastๆฏ่ฟ่กๆฐ็ปๆผๆฅ็๏ผๆไปฌ้่ฆ้่ฟskip
ๆนๆณ้ฒๆญขchildren
ๅ
็ด ๅๆฌก่ขซ้ๅฝๅฐ้ ๆไปฃ็ ้ๅคใ
ๆ็ปๅพๅฐ็่ฟๅไปฃ็ ๅฆไธ๏ผ
โโโ extension
โ โโโ src
โ โโโ auth.ts
โ โโโ codeReferencing
โ โ โโโ codeReferenceEngagementTracker.ts
โ โ โโโ compute.ts
โ โ โโโ connectionState.ts
โ โ โโโ constants.ts
โ โ โโโ handleCopliotToken.ts
โ โ โโโ handlePostInsertion.ts
โ โ โโโ headerContributor.ts
โ โ โโโ index.ts
โ โ โโโ logger.ts
โ โ โโโ matchNotifier.ts
โ โ โโโ outputChannel.ts
โ โ โโโ snippy
โ โ โ โโโ errorCreator.ts
โ โ โ โโโ index.ts
โ โ โ โโโ network.ts
โ โ โ โโโ snippy.proto.ts
โ โ โโโ telemetry
โ โ โโโ handlers.ts
โ โโโ config.ts
โ โโโ constants.ts
โ โโโ copilotPanel
โ โ โโโ common.ts
โ โ โโโ copilotListDocument.ts
โ โ โโโ panel.ts
โ โโโ diagnostics.ts
โ โโโ experiments
โ โ โโโ expFilters.ts
โ โโโ extension.ts
โ โโโ extensionStatus.ts
โ โโโ extensionTestApi.ts
โ โโโ fileSystem.ts
โ โโโ ghostText
โ โ โโโ ghostText.ts
โ โโโ git.ts
โ โโโ install
โ โ โโโ installationManager.ts
โ โโโ networkConfiguration.ts
โ โโโ proxy.ts
โ โโโ session.ts
โ โโโ statusBar.ts
โ โโโ statusBarPicker.ts
โ โโโ suggestions.ts
โ โโโ symbolDefinitionProvider.ts
โ โโโ telemetry.ts
โ โโโ telemetryDelegation.ts
โ โโโ textDocument.ts
โ โโโ textDocumentManager.ts
โ โโโ vscodeCommitFileResolver.ts
โโโ lib
โ โโโ src
โ โโโ auth
โ โ โโโ copilotToken.ts
โ โ โโโ copilotTokenManager.ts
โ โ โโโ copilotTokenNotifier.ts
โ โ โโโ error.ts
โ โโโ changeTracker.ts
โ โโโ clock.ts
โ โโโ commitFileResolver.ts
โ โโโ common
โ โ โโโ cache.ts
โ โ โโโ debounce.ts
โ โ โโโ iterableHelpers.ts
โ โ โโโ productContext.ts
โ โโโ config.ts
โ โโโ constants.ts
โ โโโ context.ts
โ โโโ copilotPanel
โ โ โโโ common.ts
โ โ โโโ panel.ts
โ โโโ cursorHistoryManager.ts
โ โโโ defaultHandlers.ts
โ โโโ diagnostics.ts
โ โโโ documentTracker.ts
โ โโโ error
โ โ โโโ userErrorNotifier.ts
โ โโโ experiments
โ โ โโโ defaultExpFilters.ts
โ โ โโโ expConfig.ts
โ โ โโโ features.ts
โ โ โโโ fetchExperiments.ts
โ โ โโโ filters.ts
โ โ โโโ granularityDirectory.ts
โ โ โโโ granularityImplementation.ts
โ โโโ ghostText
โ โ โโโ completionsCache.ts
โ โ โโโ contextualFilter.ts
โ โ โโโ contextualFilterConstants.ts
โ โ โโโ contextualFilterTree.ts
โ โ โโโ copilotCompletion.ts
โ โ โโโ debounce.ts
โ โ โโโ ghostText.ts
โ โ โโโ multilineModel.ts
โ โ โโโ multilineModelWeights.ts
โ โ โโโ normalizeIndent.ts
โ โ โโโ telemetry.ts
โ โโโ headerContributors.ts
โ โโโ installationManager.ts
โ โโโ language
โ โ โโโ generatedLanguages.ts
โ โ โโโ languageDetection.ts
โ โ โโโ languages.ts
โ โโโ logger.ts
โ โโโ network
โ โ โโโ certificateReaderCache.ts
โ โ โโโ certificateReaders.ts
โ โ โโโ certificates.ts
โ โ โโโ helix.ts
โ โ โโโ proxy.ts
โ โ โโโ proxySockets.ts
โ โโโ networkConfiguration.ts
โ โโโ networking.ts
โ โโโ notificationSender.ts
โ โโโ openai
โ โ โโโ config.ts
โ โ โโโ fetch.fake.ts
โ โ โโโ fetch.ts
โ โ โโโ openai.ts
โ โ โโโ stream.ts
โ โโโ postInsertion.ts
โ โโโ postInsertionNotifier.ts
โ โโโ progress.ts
โ โโโ prompt
โ โ โโโ neighborFiles
โ โ โ โโโ cocommittedFiles.ts
โ โ โ โโโ cursorHistoryFiles.ts
โ โ โ โโโ neighborFiles.ts
โ โ โ โโโ openTabFiles.ts
โ โ โ โโโ workspaceFiles.ts
โ โ โโโ parseBlock.ts
โ โ โโโ prompt.ts
โ โ โโโ promptLibProxy.ts
โ โ โโโ repository.ts
โ โ โโโ retrieval.ts
โ โ โโโ symbolDefinition.ts
โ โโโ repositoryControl
โ โ โโโ constants.ts
โ โ โโโ contentRestrictions.ts
โ โ โโโ policyEvaluator.ts
โ โ โโโ repositoryControl.ts
โ โ โโโ repositoryControlManager.ts
โ โโโ suggestions
โ โ โโโ anomalyDetection.ts
โ โ โโโ editDistance.ts
โ โ โโโ mlConstants.ts
โ โ โโโ restraint.ts
โ โ โโโ suggestions.ts
โ โโโ telemetry
โ โ โโโ auth.ts
โ โ โโโ azureInsights.ts
โ โ โโโ azureInsightsReporter.ts
โ โ โโโ failbot.ts
โ โ โโโ userConfig.ts
โ โโโ telemetry.ts
โ โโโ testing
โ โ โโโ config.ts
โ โ โโโ copilotToken.ts
โ โ โโโ packageRoot.ts
โ โ โโโ runtimeMode.ts
โ โ โโโ telemetry.ts
โ โ โโโ telemetryFake.ts
โ โ โโโ testHelpers.ts
โ โ โโโ tokenManager.ts
โ โโโ textDocument.ts
โ โโโ textDocumentManager.ts
โ โโโ util
โ โ โโโ documentEvaluation.ts
โ โ โโโ nodeVersion.ts
โ โ โโโ opener.ts
โ โ โโโ redaction.ts
โ โ โโโ shortCircuit.ts
โ โ โโโ typebox.ts
โ โโโ workspaceFileSystem.ts
โโโ package.json
โโโ prompt
โโโ src
โโโ elidableText
โ โโโ index.ts
โโโ tokenization
โโโ index.ts
ๅฏไปฅ็ๅฐ๏ผcopilot
ๆบ็ ๅคงไฝ็ปๆไธๅฐฑๆฏextension
ๅlib
ไธคๅฑ๏ผextension
ๆฏๆดไธชๆไปถ็ๅ
ฅๅฃ๏ผlib
ๆฏๅบๅฑๅฐ่ฃ
็ๅบ็ก่ฝๅ๏ผๅจ่ฟไธชๆธ
ๆฐ็ๆบ็ ็ปๆไธ๏ผๆๅฉไบๆไปฌ่ฟไธๆญฅๅๆ็่งฃๅ
ถไธญ็้ป่พใ
ไธ่ฟฐไปฃ็ ๅทฒ็ปๆไบคๅจGithubไธ๏ผๆ้่ฆ็ๅฐไผไผดๅฏ่ชๅ๏ผ
https://github.com/mengjian-github/copilot-analysis-new
ๅ ถๅฎ็ฎๅ็copilot็ๆฌwebpackๆททๆทๅ็ผฉ่ฆๆฏไนๅๆดๅ ้พไปฅๅๆ๏ผๆดไธชๆจกๅไฟกๆฏๅบๆฌไธๆ ๆณๆ็ฆปๅบๆฅไบ๏ผ็่ณๆฏไปไปฌไน้ด็ไพ่ตๅ ณ็ณปไนๅๅพๆดๅ ๆจก็ณใไธ่ฟcopilotๅข้ๆด้ฒไบsourcemapๆไปถ๏ผๅๅฏไปฅ่ฟไธๆญฅๆขๆฑๆบ็ ็็ปๆๅๆฟๆขไธไบๅ ณ้ฎๅ้๏ผไธบๅๆๅธฆๆฅไบไธๅฎ็ไพฟๅฉใ
ๆฌๆๆฒกๆๅไนๅ้ฃๆ ทๅฐไธปๆต็จๅๅๆไธ้๏ผๅฎ้ ไธ๏ผ่ฝ็ถไปฃ็ ็ป็ป็ปๆๆธ ๆฐไบ๏ผไฝๆฏๆบ็ ไพๆงๆ ๆณๅฎ็พ่ฟๅ๏ผsourcemapๅ ถๅฎๅธฎๅฉไนๆ้๏ผๅพๅคๆ ๅฐ่ฟ้่ฆไธๆญๅฏนๆฏ็ๆไปฃ็ ่ฟ่กๆจๆฒๅๆ๏ผๅบไบ่ฟไธช็ๆฌ็ๅบ็ก๏ผ่ฆๆณๆทฑๅ ฅไบ่งฃ๏ผ่ฟๆฏ้่ฆๅคง้็ๆถ้ดๅ็ฒพๅๆจๅฏผๅ ๅจ็้ป่พๅฎ็ฐใ