Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
782 lines (690 loc) · 73.8 KB
/
Copy pathindex.html
File metadata and controls
782 lines (690 loc) · 73.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
<!DOCTYPE html><html lang="zh-Hans" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>守株阁 - 一切都是守株待兔,如切如磋,如琢如磨。I am just joking.</title><meta name="author" content="magicliang"><meta name="copyright" content="magicliang"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="关于技术以及人生">
<meta property="og:type" content="website">
<meta property="og:title" content="守株阁">
<meta property="og:url" content="https://magicliang.github.io/index.html">
<meta property="og:site_name" content="守株阁">
<meta property="og:description" content="关于技术以及人生">
<meta property="og:locale">
<meta property="og:image" content="https://magicliang.github.io/img/rei.jpeg">
<meta property="article:author" content="magicliang">
<meta property="article:tag" content="计算机 文学">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://magicliang.github.io/img/rei.jpeg"><script type="application/ld+json">{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "守株阁",
"alternateName": [
"一切都是守株待兔,如切如磋,如琢如磨。I am just joking.",
"magicliang.github.io"
],
"url": "https://magicliang.github.io/"
}</script><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://magicliang.github.io/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css?v=5.7.0"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.3.1/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar@0.1.16/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>
(() => {
const saveToLocal = {
set: (key, value, ttl) => {
const data = { value }
if (ttl != null) {
data.expiry = Date.now() + ttl * 86400000
}
localStorage.setItem(key, JSON.stringify(data))
},
get: key => {
const itemStr = localStorage.getItem(key)
if (!itemStr) return
try {
const data = JSON.parse(itemStr)
if (data.expiry && Date.now() > data.expiry) {
localStorage.removeItem(key)
return
}
return data.value
} catch {
localStorage.removeItem(key)
}
}
}
const scriptCache = new Map()
const cssCache = new Map()
window.btf = {
saveToLocal,
getScript: (url, attr = {}) => {
if (scriptCache.has(url)) {
return scriptCache.get(url)
}
const promise = new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = url
script.async = true
for (const key in attr) {
script.setAttribute(key, attr[key])
}
script.onload = resolve
script.onerror = reject
document.head.appendChild(script)
})
scriptCache.set(url, promise)
return promise
},
getCSS: (url, id) => {
if (cssCache.has(url)) {
return cssCache.get(url)
}
const promise = new Promise((resolve, reject) => {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = url
if (id) {
link.id = id
}
link.onload = resolve
link.onerror = reject
document.head.appendChild(link)
})
cssCache.set(url, promise)
return promise
},
addGlobalFn: (key, fn, name = false, parent = window) => {
if (!true && key.startsWith('pjax')) return
const globalFn = parent.globalFn || {}
globalFn[key] = globalFn[key] || {}
globalFn[key][name || Object.keys(globalFn[key]).length] = fn
parent.globalFn = globalFn
}
}
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
const activateDarkMode = () => {
document.documentElement.dataset.theme = 'dark'
if (metaThemeColor !== null) {
metaThemeColor.setAttribute('content', 'undefined')
}
}
const activateLightMode = () => {
document.documentElement.dataset.theme = 'light'
if (metaThemeColor !== null) {
metaThemeColor.setAttribute('content', 'undefined')
}
}
btf.activateDarkMode = activateDarkMode
btf.activateLightMode = activateLightMode
const theme = saveToLocal.get('theme')
theme === 'dark' ? activateDarkMode() : theme === 'light' ? activateLightMode() : null
const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
document.documentElement.classList.toggle('hide-aside', asideStatus === 'hide')
}
const detectApple = () => {
if (/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)) {
document.documentElement.classList.add('apple')
}
}
detectApple()
})()
</script><script>const GLOBAL_CONFIG = {
root: '/',
algolia: undefined,
localSearch: {"path":"/search.json","preload":false,"top_n_per_article":1,"unescape":false,"pagination":{"enable":false,"hitsPerPage":8},"languages":{"hits_empty":"No results found for: ${query}","hits_stats":"${hits} articles found"}},
translate: {"defaultEncoding":1,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
highlight: {"plugin":"highlight.js","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false,"highlightFullpage":false,"highlightMacStyle":true},
copy: {
success: 'Copy Successful',
error: 'Copy Failed',
noSupport: 'Browser Not Supported'
},
relativeDate: {
homepage: true,
post: true
},
runtime: '',
dateSuffix: {
just: 'Just now',
min: 'minutes ago',
hour: 'hours ago',
day: 'days ago',
month: 'months ago'
},
copyright: {"limitCount":50,"languages":{"author":"Author: magicliang","link":"Link: ","source":"Source: 守株阁","info":"Copyright belongs to the author. For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source."}},
lightbox: 'null',
Snackbar: {"chs_to_cht":"You have switched to Traditional Chinese","cht_to_chs":"You have switched to Simplified Chinese","day_to_night":"You have switched to Dark Mode","night_to_day":"You have switched to Light Mode","bgLight":"#49b1f5","bgDark":"#2d3035","position":"bottom-left"},
infinitegrid: {
js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid@4.13.0/dist/infinitegrid.min.js',
buttonText: 'Load More'
},
isPhotoFigcaption: true,
islazyloadPlugin: true,
isAnchor: false,
percent: {
toc: true,
rightside: true,
},
autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
title: '守株阁',
isHighlightShrink: false,
isToc: false,
pageType: 'home'
}</script><meta name="generator" content="Hexo 8.1.2"><link rel="alternate" href="/atom.xml" title="守株阁" type="application/atom+xml">
<link href="https://cdn.bootcss.com/KaTeX/0.11.1/katex.min.css" rel="stylesheet" /></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">Loading...</div></div></div><script>(()=>{
const $loadingBox = document.getElementById('loading-box')
const $body = document.body
const preloader = {
endLoading: () => {
if ($loadingBox.classList.contains('loaded')) return
$body.style.overflow = ''
$loadingBox.classList.add('loaded')
},
initLoading: () => {
$body.style.overflow = 'hidden'
$loadingBox.classList.remove('loaded')
}
}
preloader.initLoading()
if (document.readyState === 'complete') {
preloader.endLoading()
} else {
window.addEventListener('load', preloader.endLoading)
document.addEventListener('DOMContentLoaded', preloader.endLoading)
// Add timeout protection: force end after 7 seconds
setTimeout(preloader.endLoading, 7000)
}
if (true) {
btf.addGlobalFn('pjaxSend', preloader.initLoading, 'preloader_init')
btf.addGlobalFn('pjaxComplete', preloader.endLoading, 'preloader_end')
}
})()</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img text-center"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/rei.jpeg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data text-center"><a href="/archives/"><div class="headline">Articles</div><div class="length-num">2269</div></a><a href="/tags/"><div class="headline">Tags</div><div class="length-num">2178</div></a><a href="/categories/"><div class="headline">Categories</div><div class="length-num">40</div></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> Archives</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> About</span></a></div></div></div></div><div class="page" id="body-wrap"><header class="full_page" id="page-header" style="background-image: url(/img/eva-wallpaper.jpg);"><nav id="nav"><span id="blog-info"><a class="nav-site-title" href="/"><span class="site-name">守株阁</span></a></span><div id="menus"><div id="search-button"><span class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> Search</span></span></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> Home</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> Archives</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> Tags</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> Categories</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> About</span></a></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="site-info"><h1 id="site-title">守株阁</h1><div id="site-subtitle"><span id="subtitle"></span></div><div id="site_social_icons"><a class="social-icon" href="https://github.com/magicliang" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:magicliang@qq.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div id="scroll-down"><i class="fas fa-angle-down scroll-down-effects"></i></div></header><main class="layout" id="content-inner"><div class="recent-posts nc" id="recent-posts"><div class="recent-post-items"><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA04-%E9%AB%98%E6%B2%B9%E4%BB%B7%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%86%E8%BD%AC/" title="石油危机04:1981—1986,高油价为什么逆转?">石油危机04:1981—1986,高油价为什么逆转?</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:13:00.000Z" title="Created 2026-10-29 21:13:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:36.090Z" title="Updated 2026-10-31 00:14:36">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB/">国际关系</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%BB%8F%E6%B5%8E%E5%8F%B2/">经济史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA/">石油危机</a></span></div><div class="content">第1篇 · 第2篇 · 第3篇 · 第4篇(本篇) 1986 年的油价暴跌,结束的是一种维持高价格的市场安排。它没有结束石油在交通和工业中的重要性,也没有把资源控制权交还给危机前的国际石油公司。 两次危机之后,消费国逐渐减少单位产出所需的石油,开发其他能源,扩大中东之外的供应;1980 年代初的衰退又压低了需求。OPEC 若要维持官方售价,就必须让一部分生产能力闲置。这个调整在相当程度上落到了沙特身上。到 1985 年,沙特改以争取销量为先,并通过新的销售合同把降价风险更多留给自己。此前几年的缓慢调整,遂在 1986 年集中表现为价格急跌。 这条解释能够回答为什么市场会变,却还不能单独回答为什么价格在那个时间、以那种速度下跌。后一个问题必须进入配额谈判、炼厂采购和合同定价。金融与冷战也参与其中,但需要分别检验:石油美元回流确有其事;美国希望限制苏联收入也有文件;这些事实并不自动证明存在一份控制整个市场的秘密总协议。 本篇年表:从需求收缩到价格失守 下表只列改变因果判断的节点。年均产量、季度日均产量和某个月的低点不能直接相除;官方售价也不能与另一油种的现货最低价拼接成一条曲线。 ...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA03-%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8F%88%E5%8F%91%E7%94%9F%E4%B8%80%E6%AC%A1%E5%8D%B1%E6%9C%BA/" title="石油危机03:1974—1981,为什么又发生一次危机?">石油危机03:1974—1981,为什么又发生一次危机?</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:12:00.000Z" title="Created 2026-10-29 21:12:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:36.089Z" title="Updated 2026-10-31 00:14:36">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB/">国际关系</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%BB%8F%E6%B5%8E%E5%8F%B2/">经济史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA/">石油危机</a></span></div><div class="content">第1篇 · 第2篇 · 第3篇(本篇) · 第4篇 1979 年油价再次急涨,不能只用“伊朗革命造成减产”解释。革命确实使一个主要出口国的供应中断,但别国同时增产,伊朗后来也恢复出口。全年统计甚至显示,1979 年世界原油产量高于 1978 年。真正需要解释的是:短期断流怎样改变企业对下一船油的判断,为什么恢复生产没有立即带来价格回落,以及 1980 年战争再度切断供应时,市场为何逐渐出现不同反应。 第一次危机后的调整已经启动,却还没有充分改变交通工具、工业设备和供货关系。伊朗的政治冲突首先削减当期供应,又使未来供应变得难以预测;消费国、炼厂和贸易商增加安全库存的愿望,与实际用油需求共同推高了采购压力。随后发生的两伊战争增加了设施损坏和出口通道受阻,但到 1980 年秋,进口国库存较充裕、需求已下降,能够采取更有针对性的应对。两次危机存在共同的供需约束,却不是同一种政治行动的重复。 已经开始调整,为什么仍然脆弱 1974 年以后,消费国确实建立了新制度。国际能源署及其《国际能源计划》把储备、需求限制和紧急分配纳入合作安排。不过,储备义务不等于各国政府已经拥有一座装满原油的公共油库...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA02-%E6%88%98%E4%BA%89%E6%80%8E%E6%A0%B7%E5%8F%98%E6%88%90%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA/" title="石油危机02:1973—1974,战争怎样变成石油危机?">石油危机02:1973—1974,战争怎样变成石油危机?</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:11:00.000Z" title="Created 2026-10-29 21:11:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:36.081Z" title="Updated 2026-10-31 00:14:36">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB/">国际关系</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%BB%8F%E6%B5%8E%E5%8F%B2/">经济史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA/">石油危机</a></span></div><div class="content">第1篇 · 第2篇(本篇) · 第3篇 · 第4篇 1973 年的中东战争没有炸掉全世界的油田。它改变的是产油国愿意生产多少、卖给谁,以及以什么条件出售。已经趋紧的市场承受了实际减产,企业重新分配货源,政府决定哪些价格可以上涨、哪些用户优先获得燃料。短缺、涨价和排队由此相互强化,但不是同一件事。 这场危机也没有一个统一的指挥部。埃及希望战争打破外交僵局;沙特试图迫使美国推动以色列撤军,同时维持与美国的关系;伊朗没有参加阿拉伯禁运,却支持大幅提价;国际石油公司既担心失去产油国的经营权,也在上涨的价格中获得利润。解释危机,必须把这些行动连起来,又不能把它们写成一个预先商定的计划。 从战场变化到出口限制 战争爆发前,西奈半岛和戈兰高地的部分地区仍处于以色列自 1967 年战争以来的占领之下。埃及总统萨达特曾提出临时撤军、重开苏伊士运河等方案;美国政府内部对是否施压以色列存在分歧,谈判未能改变僵局。美国国务院历史办公室的回顾显示,美国决策层低估了埃及、叙利亚发动进攻的可能性。这是关于美国认知的证据,不能据此推断阿拉伯各国共享同一份战争计划。1 10 月 6 日,埃及军队在苏伊士运河方向、...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA01-%E5%8D%B1%E6%9C%BA%E4%B9%8B%E5%89%8D%E8%B0%81%E6%8E%A7%E5%88%B6%E7%9F%B3%E6%B2%B9/" title="石油危机01:危机之前,谁控制石油?">石油危机01:危机之前,谁控制石油?</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:10:00.000Z" title="Created 2026-10-29 21:10:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:36.081Z" title="Updated 2026-10-31 00:14:36">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB/">国际关系</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%BB%8F%E6%B5%8E%E5%8F%B2/">经济史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA/">石油危机</a></span></div><div class="content">第1篇(本篇) · 第2篇 · 第3篇 · 第4篇 1973 年秋天以前,石油世界已经在发生权力转移。产油国争取的,不只是每桶油多收几分钱,而是决定开采多少、卖给谁、怎样定价的权力。国际石油公司仍然控制大量经营、运输和销售环节,却越来越难用另一处廉价供应,压住某个产油国的要求。与此同时,美国逐渐失去过去能够迅速增加供应的余地,欧洲和日本的经济增长又增加了对进口石油的需要。 因此,石油危机的前史不能简化为“西方拥有石油,后来阿拉伯国家把它收了回来”。资源归属、经营管理、税收分成、市场渠道和军事保护,是几种不同的权力;二战后至 1973 年 9 月,它们的分配发生了变化,却没有整齐地从一方全部交到另一方手里。战争即将改变这场谈判的速度和方式,但谈判早已开始。 石油怎样成为难以替代的投入 石油的重要性首先来自用途。汽油、柴油和航空燃料便于携带,适合车辆、舰船和飞机;燃料油进入工业锅炉、供暖和发电;石脑油等原料进入石化工业。公路、汽车、机场、炼厂和化工装置一旦建成,整个生产生活体系就会沿着已有设备运转。供应中断时,煤炭储量再丰富,也不能直接倒进汽车油箱;电厂能够改烧另一种燃料,也不等于改...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E4%B8%AD%E5%9B%BD%E8%BE%B9%E7%96%86%E5%8F%B204-%E5%B8%95%E7%B1%B3%E5%B0%94%E4%B8%8E%E4%B8%AD%E4%BA%9A%E8%BE%B9%E7%95%8C/" title="中国边疆史04:帕米尔与中亚边界">中国边疆史04:帕米尔与中亚边界</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:04:00.000Z" title="Created 2026-10-29 21:04:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:35.958Z" title="Updated 2026-10-31 00:14:35">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E8%BE%B9%E7%96%86%E5%8F%B2/">边疆史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB%E5%8F%B2/">国际关系史</a></span></div><div class="content">本篇属于《中国边疆、国家形成与领土及海洋争议》。系列导读与总年表。 帕米尔边界由几轮不同性质的安排形成。1884年清俄勘界确定了部分山地边界,却在乌孜别里山口以南留下两条分岔的走向;十九世纪九十年代,俄军推进、清方交涉、阿富汗驻军和英俄谈判改变了当地控制。1895年英俄协议划分势力范围,明确保留了同中国政府协商中国疆界的事项。今天中国与塔吉克斯坦的国界,则由两国自己的边界协定、补充协定和勘界议定书确认。把这些文件合并成一次“俄国取得帕米尔”,会漏掉决定法律关系与居民生活的差别。 “外西北”也是一个需要限定的历史称谓。它可以指向清俄西段划界造成的领土变动,但不能把今天的哈萨克斯坦、吉尔吉斯斯坦和塔吉克斯坦写成仍由俄罗斯管理的地区。三国分别与中国订立边界文件,其自身的国家形成和外交选择,是现代边界史的一部分。 山口以南为什么留下两条线 帕米尔不是一片没有社会的高原。瓦罕等河谷有地方统治者、村落、耕地和宗教网络;高山牧场与山口又连接跨季节移动的人群。清朝、浩罕、布哈拉和阿富汗的联系及权力范围并不重合。向某位统治者纳贡、接受地方头人的任命、允许一支军队通过,与一条双方同意且能够持续执行...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E4%B8%AD%E5%9B%BD%E8%BE%B9%E7%96%86%E5%8F%B203-%E5%A4%96%E8%A5%BF%E5%8C%97%E4%B8%8E%E4%BC%8A%E7%8A%81%E4%BA%A4%E6%B6%89/" title="中国边疆史03:外西北与伊犁交涉">中国边疆史03:外西北与伊犁交涉</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:03:00.000Z" title="Created 2026-10-29 21:03:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:35.930Z" title="Updated 2026-10-31 00:14:35">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E8%BE%B9%E7%96%86%E5%8F%B2/">边疆史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB%E5%8F%B2/">国际关系史</a></span></div><div class="content">本篇属于《中国边疆、国家形成与领土及海洋争议》。系列导读与总年表。 1864 年的塔城勘界和 1881 年的伊犁交涉,不能合并成一次割地,也不能用“左宗棠出兵、曾纪泽谈判,失地全部收回”概括。前者把包括清朝卡伦和纳租牧场在内的边疆空间划入两国界线;后者规定俄方交还伊犁大部、恢复清朝统治,却保留了西部割让、其他地段改界、赔款和商业特权。1881 年相对于未获清廷批准的 1879 年方案,确有重要改善;相对于占领以前的状况,仍有显著损失。这两个比较基准必须同时保留。1864 年约第 4—5 条;1879 年约第 7、18 条;1881 年约第 1、6—9 条 一片边疆,不是一种统治关系 “外西北”适合说明中国历史叙述中对西北失地的回顾,却不能代替逐段调查。清代文书所说的伊犁、塔尔巴哈台、科布多、哈萨克游牧地,政治关系并不相同。乾隆朝对哈萨克首领的册封、对越卡游牧的许可与征收租马,也不同于在某地设置衙门、派驻官兵。张帅依据《清实录》和满文寄信档汉译所作研究指出,1767 年形成的办法允许部分牧民入卡过冬,按牲畜征收租马,春季再退出;牧民不断寻求冬牧场,参与塑造了这套制度。张帅,〈清代...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E4%B8%AD%E5%9B%BD%E8%BE%B9%E7%96%86%E5%8F%B202-%E5%A4%96%E4%B8%9C%E5%8C%97%E7%9A%84%E9%A2%86%E5%9C%9F%E4%B8%8E%E7%BB%9F%E6%B2%BB%E5%8F%98%E5%8C%96/" title="中国边疆史02:外东北的领土与统治变化">中国边疆史02:外东北的领土与统治变化</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:02:00.000Z" title="Created 2026-10-29 21:02:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:35.922Z" title="Updated 2026-10-31 00:14:35">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E8%BE%B9%E7%96%86%E5%8F%B2/">边疆史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB%E5%8F%B2/">国际关系史</a></span></div><div class="content">本篇属于《中国边疆、国家形成与领土及海洋争议》。系列导读与总年表。 1858 年和 1860 年的中俄条约,改变了清朝与俄国在黑龙江、乌苏里江及日本海沿岸的边界。这次变化来自几个相互配合的过程:俄国先用航行、设站和移民增加当地存在,再利用清朝内外战争造成的压力,取得划界条约,最后通过地方行政与人口控制落实统治。不过,“外东北”并不是当时一个界线固定的行政区;大陆边界、江东六十四屯的居民管辖、库页岛的俄日竞争,也没有在同一天、按同一种法律方式全部解决。《瑷珲条约》第 1 条、《北京条约》第 1、3 条 本篇所说的“外东北”,主要指黑龙江以北、乌苏里江以东的大陆地区;库页岛因清俄日关系另作一节。条约取得的土地、地方实际控制与居民保留权利,分别核查,不用一个总面积合并。 河流怎样成为扩张的条件 十八世纪的黑龙江下游及库页岛,存在清朝官员、地方首领和居民之间的贡貂、赏赐与贸易联系。它不是处处设县、逐户登记的统治,也不是没有政治联系的空白。俄文学者扎布罗夫斯卡娅讨论三姓副都统与下游诸族关系时,指出地方首领任命、貂皮贡纳和回赐可以并行于相当程度的地方自主。日本国立阿伊努民族博物馆展示的《桦...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E4%B8%AD%E5%9B%BD%E8%BE%B9%E7%96%86%E5%8F%B201-%E6%B8%85%E4%BF%84%E6%9C%80%E5%88%9D%E7%9A%84%E8%BE%B9%E7%95%8C/" title="中国边疆史01:清俄最初的边界">中国边疆史01:清俄最初的边界</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:01:00.000Z" title="Created 2026-10-29 21:01:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:35.903Z" title="Updated 2026-10-31 00:14:35">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E8%BE%B9%E7%96%86%E5%8F%B2/">边疆史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB%E5%8F%B2/">国际关系史</a></span></div><div class="content">本篇属于《中国边疆、国家形成与领土及海洋争议》。系列导读与总年表。 1689 年的《尼布楚条约》没有把一条早已清楚的现代国界重新描一遍,也没有把整个西伯利亚或贝加尔湖从清朝划给俄国。它解决的是黑龙江上游及其北侧的一组具体冲突:戈尔比察河、额尔古纳河及山岭分水线如何分界,雅克萨俄人堡垒是否保留,逃人怎样处置,边民冲突怎样避免升级为战争。文本署 1727 年日期、1728 年完成签押文本交换的《恰克图条约》,又把蒙古方向的划界、通商和交涉程序结合起来。两次谈判把重叠的征贡、军事占领与政治要求,变成双方承认的边界;它们没有消除全部地理疑难,也没有征求沿线每个居民群体的意见。《尼布楚条约》俄文正式抄本、《恰克图条约》俄文正式抄本 理解这段历史,先要分清三个范围:清廷声称应由自己管辖的地方,实际能够征贡、驻军和调动居民的地方,最后经条约取得对方承认的地方。三者有关联,却不总是重合。条约能够证明双方最后同意了什么,不能单独证明此前每一处山川始终属于谁。 黑龙江沿岸并不是等待占领的空地 俄国人进入黑龙江流域时,面对的是有村落、耕地、首领和政治关系的社会。达斡尔人分布于黑龙江北岸及精奇里江等河...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E4%B8%AD%E5%9B%BD%E8%BE%B9%E7%96%86%E5%8F%B200-%E5%AF%BC%E8%AF%BB%E4%B8%8E%E6%80%BB%E5%B9%B4%E8%A1%A8/" title="中国边疆史00:导读与总年表">中国边疆史00:导读与总年表</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:00:00.000Z" title="Created 2026-10-29 21:00:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:35.903Z" title="Updated 2026-10-31 00:14:35">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E8%BE%B9%E7%96%86%E5%8F%B2/">边疆史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E5%9B%BD%E9%99%85%E5%85%B3%E7%B3%BB%E5%8F%B2/">国际关系史</a></span></div><div class="content">一张边界图会把不同年代的过程压成同一种线条。战争中的驻军、条约上的划界、地方官能够征税的范围、居民往返的牧场,往往并不重合。判断一段边界怎样形成,需要把这些过程重新分开。 本系列讨论与俄国扩张有关的北部和西北边疆,以及蒙古、图瓦、西藏、新疆、中印边界、台湾、东海与南海。这里有已经通过条约处理的国界,也有仍在持续的主权、地位或海洋权利争议。某个地区曾经发生征服或割让,不等于今天仍有同样的国家间争议;反过来,今天承认一条边界,也不要求把它的形成过程描述成公平、自愿的交易。 阅读顺序与篇目 系列安排二十篇正文。当前已经完成的是第一至第四篇;下列其余篇目为后续范围,尚未交付正文。可以按地域阅读,也可以依次了解统治如何建立、边界如何议定、居民怎样承受变化。 表1:系列篇目与主要问题。未完成篇目不设置文章链接。 组别 篇目与主体时段 主要解释内容 清俄与中亚 01 清俄最初的边界;02 外东北的领土与统治变化;03 外西北与伊犁交涉;04 帕米尔与中亚边界 十七世纪以来的征贡、战争、条约与居民迁移;现代中亚国家分别订界 蒙古、图瓦与俄苏关系 05 外蒙古的独立,清代至19...</div></div></div><div class="recent-post-item"><div class="recent-post-info no-cover"><a class="article-title" href="/2026/10/29/%E4%BC%8A%E6%9C%97%E4%BC%8A%E6%96%AF%E5%85%B0%E9%9D%A9%E5%91%BD00-%E5%AF%BC%E8%AF%BB%E4%B8%8E%E6%80%BB%E5%B9%B4%E8%A1%A8/" title="伊朗伊斯兰革命00:导读与总年表">伊朗伊斯兰革命00:导读与总年表</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">Created</span><time class="post-meta-date-created" datetime="2026-10-29T13:00:00.000Z" title="Created 2026-10-29 21:00:00">2026-10-29</time><span class="article-meta-separator">|</span><i class="fas fa-history"></i><span class="article-meta-label">Updated</span><time class="post-meta-date-updated" datetime="2026-10-30T16:14:35.989Z" title="Updated 2026-10-31 00:14:35">2026-10-31</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%8E%86%E5%8F%B2/">历史</a></span><span class="article-meta tags"><span class="article-meta-separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E4%BC%8A%E6%9C%97%E5%8E%86%E5%8F%B2/">伊朗历史</a><span class="article-meta-link">•</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E4%BC%8A%E6%96%AF%E5%85%B0%E9%9D%A9%E5%91%BD/">伊斯兰革命</a></span></div><div class="content">1979年革命推翻了巴列维王朝,却没有在同一天决定新国家的全部制度。反王朝动员、旧政府瓦解、革命联盟分裂、对外战争和最高权力制度化,是先后发生、彼此影响的几个过程。十二篇文章沿着这些变化,追踪谁作出了决定、依靠什么机构执行,以及哪些人获益、反对或承担代价。 系列从1905年立宪运动写到1989年修宪与领导权交接,重点放在1977—1983年。正文中的判断以具体事件、文件和研究为依据;死伤、公投及兵力数字保留统计口径,争议资料注明能够证明什么。各篇附有年表、就近引用和实际阅读范围。 十二篇的阅读顺序 篇次与文章 时间范围 主要问题 01:宪法、王权与现代国家 1905—1941 立宪、国家建设与外国干预怎样改变权力关系? 02:石油国有化与1953年政变 1941—1953 外国行动与国内政治力量怎样共同推翻摩萨台? 03:改革与王朝危机 1953—1977 土地、教育和经济改革为何没有换来稳定的政治合作? 04:抗议如何扩散 1977—1978年9月 公开批评、悼念、地方冲突与传言怎样形成全国动员? 05:罢工与国家失灵 1978年秋—1979年1...</div></div></div></div><nav id="pagination"><div class="pagination"><span class="page-number current">1</span><a class="page-number" href="/page/2/#content-inner">2</a><span class="space">…</span><a class="page-number" href="/page/227/#content-inner">227</a><a class="extend next" rel="next" href="/page/2/#content-inner"><i class="fas fa-chevron-right fa-fw"></i></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info text-center"><div class="avatar-img"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/rei.jpeg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info-name">magicliang</div><div class="author-info-description">关于技术以及人生</div><div class="site-data"><a href="/archives/"><div class="headline">Articles</div><div class="length-num">2269</div></a><a href="/tags/"><div class="headline">Tags</div><div class="length-num">2178</div></a><a href="/categories/"><div class="headline">Categories</div><div class="length-num">40</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/magicliang"><i class="fab fa-github"></i><span>Github</span></a><div class="card-info-social-icons"><a class="social-icon" href="https://github.com/magicliang" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:magicliang@qq.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>Announcement</span></div><div class="announcement_content">人生只是,守株待兔</div></div><div class="sticky_layout"><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>Recent Posts</span></div><div class="aside-list"><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA04-%E9%AB%98%E6%B2%B9%E4%BB%B7%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%86%E8%BD%AC/" title="石油危机04:1981—1986,高油价为什么逆转?">石油危机04:1981—1986,高油价为什么逆转?</a><time datetime="2026-10-29T13:13:00.000Z" title="Created 2026-10-29 21:13:00">2026-10-29</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA03-%E4%B8%BA%E4%BB%80%E4%B9%88%E5%8F%88%E5%8F%91%E7%94%9F%E4%B8%80%E6%AC%A1%E5%8D%B1%E6%9C%BA/" title="石油危机03:1974—1981,为什么又发生一次危机?">石油危机03:1974—1981,为什么又发生一次危机?</a><time datetime="2026-10-29T13:12:00.000Z" title="Created 2026-10-29 21:12:00">2026-10-29</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA02-%E6%88%98%E4%BA%89%E6%80%8E%E6%A0%B7%E5%8F%98%E6%88%90%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA/" title="石油危机02:1973—1974,战争怎样变成石油危机?">石油危机02:1973—1974,战争怎样变成石油危机?</a><time datetime="2026-10-29T13:11:00.000Z" title="Created 2026-10-29 21:11:00">2026-10-29</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2026/10/29/%E7%9F%B3%E6%B2%B9%E5%8D%B1%E6%9C%BA01-%E5%8D%B1%E6%9C%BA%E4%B9%8B%E5%89%8D%E8%B0%81%E6%8E%A7%E5%88%B6%E7%9F%B3%E6%B2%B9/" title="石油危机01:危机之前,谁控制石油?">石油危机01:危机之前,谁控制石油?</a><time datetime="2026-10-29T13:10:00.000Z" title="Created 2026-10-29 21:10:00">2026-10-29</time></div></div><div class="aside-list-item no-cover"><div class="content"><a class="title" href="/2026/10/29/%E4%B8%AD%E5%9B%BD%E8%BE%B9%E7%96%86%E5%8F%B204-%E5%B8%95%E7%B1%B3%E5%B0%94%E4%B8%8E%E4%B8%AD%E4%BA%9A%E8%BE%B9%E7%95%8C/" title="中国边疆史04:帕米尔与中亚边界">中国边疆史04:帕米尔与中亚边界</a><time datetime="2026-10-29T13:04:00.000Z" title="Created 2026-10-29 21:04:00">2026-10-29</time></div></div></div></div><div class="card-widget card-categories"><div class="item-headline"><i class="fas fa-folder-open"></i><span>Categories</span><a class="card-more-btn" href="/categories/" title="View More">
<i class="fas fa-angle-right"></i></a></div>
<ul class="card-category-list" id="aside-cat-list">
<li class="card-category-list-item "><a class="card-category-list-link" href="/categories/AI/"><span class="card-category-list-name">AI</span><span class="card-category-list-count">80</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Java/"><span class="card-category-list-name">Java</span><span class="card-category-list-count">116</span></a><ul class="card-category-list child"><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Java/%E6%8C%81%E4%B9%85%E5%8C%96/"><span class="card-category-list-name">持久化</span><span class="card-category-list-count">2</span></a></li></ul></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Java-EE-%E4%BC%81%E4%B8%9A%E5%BA%94%E7%94%A8/"><span class="card-category-list-name">Java EE 企业应用</span><span class="card-category-list-count">24</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Kotlin-%E8%AF%AD%E8%A8%80%E4%B8%8E-JVM-%E5%B7%A5%E7%A8%8B/"><span class="card-category-list-name">Kotlin 语言与 JVM 工程</span><span class="card-category-list-count">48</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Perl/"><span class="card-category-list-name">Perl</span><span class="card-category-list-count">60</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Python-%E8%AF%AD%E8%A8%80%E4%B8%8E%E5%B7%A5%E7%A8%8B/"><span class="card-category-list-name">Python 语言与工程</span><span class="card-category-list-count">31</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/Python%EF%BC%9A%E4%BB%8E%E5%AF%B9%E8%B1%A1%E6%A8%A1%E5%9E%8B%E5%88%B0%E5%B9%B6%E5%8F%91%E4%B8%8E%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5/"><span class="card-category-list-name">Python:从对象模型到并发与工程实践</span><span class="card-category-list-count">17</span></a></li>
</ul></div><div class="card-widget card-tags"><div class="item-headline"><i class="fas fa-tags"></i><span>Tags</span></div><div class="card-tag-cloud"><a href="/tags/%E5%BD%B1%E8%AF%84/" style="font-size: 1.24em; color: rgb(178, 191, 50);">影评</a><a href="/tags/%E8%AF%BA%E5%85%B0/" style="font-size: 1.15em; color: rgb(114, 50, 188);">诺兰</a><a href="/tags/JVM/" style="font-size: 1.33em; color: rgb(50, 84, 60);">JVM</a><a href="/tags/Java/" style="font-size: 1.45em; color: rgb(50, 51, 193);">Java</a><a href="/tags/%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86/" style="font-size: 1.17em; color: rgb(54, 134, 66);">异常处理</a><a href="/tags/%E5%8C%BA%E5%9D%97%E9%93%BE/" style="font-size: 1.43em; color: rgb(50, 63, 153);">区块链</a><a href="/tags/Hyperledger/" style="font-size: 1.15em; color: rgb(50, 183, 158);">Hyperledger</a><a href="/tags/Corda/" style="font-size: 1.15em; color: rgb(115, 162, 102);">Corda</a><a href="/tags/%E7%A7%81%E6%9C%89%E9%93%BE/" style="font-size: 1.15em; color: rgb(177, 100, 116);">私有链</a><a href="/tags/%E8%81%94%E7%9B%9F%E9%93%BE/" style="font-size: 1.15em; color: rgb(94, 50, 176);">联盟链</a><a href="/tags/%E5%85%B1%E8%AF%86%E7%AE%97%E6%B3%95/" style="font-size: 1.17em; color: rgb(50, 55, 50);">共识算法</a><a href="/tags/javac/" style="font-size: 1.15em; color: rgb(50, 50, 50);">javac</a><a href="/tags/JIT/" style="font-size: 1.17em; color: rgb(113, 97, 50);">JIT</a><a href="/tags/%E5%AD%97%E8%8A%82%E7%A0%81/" style="font-size: 1.17em; color: rgb(136, 50, 173);">字节码</a><a href="/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" style="font-size: 1.17em; color: rgb(104, 187, 50);">性能优化</a><a href="/tags/%E7%A7%91%E5%B9%BB/" style="font-size: 1.15em; color: rgb(195, 130, 127);">科幻</a><a href="/tags/Docker/" style="font-size: 1.22em; color: rgb(121, 189, 86);">Docker</a><a href="/tags/Socket/" style="font-size: 1.2em; color: rgb(200, 148, 118);">Socket</a><a href="/tags/JavaScript/" style="font-size: 1.26em; color: rgb(180, 50, 57);">JavaScript</a><a href="/tags/KOA/" style="font-size: 1.15em; color: rgb(115, 50, 142);">KOA</a><a href="/tags/%E6%95%B0%E6%8D%AE%E5%BA%93/" style="font-size: 1.29em; color: rgb(50, 53, 134);">数据库</a><a href="/tags/MySQL/" style="font-size: 1.27em; color: rgb(58, 186, 60);">MySQL</a><a href="/tags/MariaDB/" style="font-size: 1.15em; color: rgb(50, 50, 171);">MariaDB</a><a href="/tags/Linux/" style="font-size: 1.34em; color: rgb(50, 144, 50);">Linux</a><a href="/tags/%E8%99%9A%E6%8B%9F%E5%8C%96/" style="font-size: 1.19em; color: rgb(159, 93, 50);">虚拟化</a><a href="/tags/hypervisor/" style="font-size: 1.15em; color: rgb(67, 194, 65);">hypervisor</a><a href="/tags/github/" style="font-size: 1.15em; color: rgb(141, 87, 50);">github</a><a href="/tags/hexo/" style="font-size: 1.15em; color: rgb(187, 194, 130);">hexo</a><a href="/tags/%E4%BA%92%E8%81%94%E7%BD%91%E9%87%91%E8%9E%8D/" style="font-size: 1.15em; color: rgb(195, 181, 50);">互联网金融</a><a href="/tags/FinTech/" style="font-size: 1.17em; color: rgb(170, 176, 99);">FinTech</a><a href="/tags/Python/" style="font-size: 1.41em; color: rgb(166, 50, 52);">Python</a><a href="/tags/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" style="font-size: 1.17em; color: rgb(50, 121, 149);">面向对象</a><a href="/tags/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/" style="font-size: 1.36em; color: rgb(84, 59, 53);">编程语言</a><a href="/tags/%E7%BC%96%E7%A8%8B%E8%8C%83%E5%BC%8F/" style="font-size: 1.15em; color: rgb(134, 50, 50);">编程范式</a><a href="/tags/tag/" style="font-size: 1.15em; color: rgb(79, 154, 91);">tag</a><a href="/tags/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/" style="font-size: 1.38em; color: rgb(164, 187, 192);">操作系统</a><a href="/tags/Go/" style="font-size: 1.4em; color: rgb(193, 153, 143);">Go</a><a href="/tags/vim/" style="font-size: 1.15em; color: rgb(82, 50, 50);">vim</a><a href="/tags/%E5%A4%A7%E6%95%B0%E6%8D%AE/" style="font-size: 1.31em; color: rgb(65, 179, 99);">大数据</a><a href="/tags/%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84/" style="font-size: 1.19em; color: rgb(121, 78, 177);">体系结构</a></div></div><div class="card-widget card-archives">
<div class="item-headline"><i class="fas fa-archive"></i><span>Archives</span><a class="card-more-btn" href="/archives/"
title="View More">
<i class="fas fa-angle-right"></i>
</a></div>
<ul class="card-archive-list">
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/10/">
<span class="card-archive-list-date">
October 2026
</span>
<span class="card-archive-list-count">1363</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/09/">
<span class="card-archive-list-date">
September 2026
</span>
<span class="card-archive-list-count">244</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/08/">
<span class="card-archive-list-date">
August 2026
</span>
<span class="card-archive-list-count">100</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/07/">
<span class="card-archive-list-date">
July 2026
</span>
<span class="card-archive-list-count">54</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/06/">
<span class="card-archive-list-date">
June 2026
</span>
<span class="card-archive-list-count">80</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/05/">
<span class="card-archive-list-date">
May 2026
</span>
<span class="card-archive-list-count">90</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/04/">
<span class="card-archive-list-date">
April 2026
</span>
<span class="card-archive-list-count">19</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/03/">
<span class="card-archive-list-date">
March 2026
</span>
<span class="card-archive-list-count">14</span>
</a>
</li>
</ul>
</div><div class="card-widget card-webinfo"><div class="item-headline"><i class="fas fa-chart-line"></i><span>Website Info</span></div><div class="webinfo"><div class="webinfo-item"><div class="item-name">Article Count :</div><div class="item-count">2269</div></div><div class="webinfo-item"><div class="item-name">Total Word Count :</div><div class="item-count">8272.3k</div></div><div class="webinfo-item"><div class="item-name">Unique Visitors :</div><div class="item-count" id="busuanzi_value_site_uv"><i class="fa-solid fa-spinner fa-spin"></i></div></div><div class="webinfo-item"><div class="item-name">Page Views :</div><div class="item-count" id="busuanzi_value_site_pv"><i class="fa-solid fa-spinner fa-spin"></i></div></div><div class="webinfo-item"><div class="item-name">Last Update :</div><div class="item-count" id="last-push-date" data-lastPushDate="2026-10-30T16:15:24.521Z"><i class="fa-solid fa-spinner fa-spin"></i></div></div></div></div></div></div></main><footer id="footer"><div class="footer-other"><div class="footer-copyright"><span class="copyright">© 2017 - 2026 By magicliang</span><span class="framework-info"><span>Framework </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo 8.1.2</a><span class="footer-separator">|</span><span>Theme </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly 5.7.0</a></span></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="translateLink" type="button" title="Toggle Between Traditional and Simplified Chinese">簡</button><button id="darkmode" type="button" title="Toggle Between Light and Dark Mode"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="Toggle Between Single-column and Double-column"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="Settings"><i class="fas fa-cog fa-spin"></i></button><button id="go-up" type="button" title="Back to Top"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js?v=5.7.0"></script><script src="/js/main.js?v=5.7.0"></script><script src="/js/tw_cn.js?v=5.7.0"></script><script src="https://cdn.jsdelivr.net/npm/instant.page@5.2.0/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.1.3/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar@0.1.16/dist/snackbar.min.js"></script><div class="js-pjax"><script>window.typedJSFn = {
init: str => {
window.typed = new Typed('#subtitle', Object.assign({
strings: str,
startDelay: 300,
typeSpeed: 150,
loop: true,
backSpeed: 50,
}, null))
},
run: subtitleType => {
if (true) {
if (typeof Typed === 'function') {
subtitleType()
} else {
btf.getScript('https://cdn.jsdelivr.net/npm/typed.js@3.0.0/dist/typed.umd.min.js').then(subtitleType)
}
} else {
subtitleType()
}
},
processSubtitle: (content, extraContents = []) => {
if (true) {
const sub = ["一切都是守株待兔,如切如磋,如琢如磨。","I am just joking."].slice()
if (extraContents.length > 0) {
sub.unshift(...extraContents)
}
if (typeof content === 'string') {
sub.unshift(content)
} else if (Array.isArray(content)) {
sub.unshift(...content)
}
sub.length > 0 && typedJSFn.init(sub)
} else {
document.getElementById('subtitle').textContent = typeof content === 'string' ? content :
(Array.isArray(content) && content.length > 0 ? content[0] : '')
}
}
}
btf.addGlobalFn('pjaxSendOnce', () => { typed && typed.destroy() }, 'typedDestroy')
</script><script>function subtitleType () {
typedJSFn.processSubtitle(["一切都是守株待兔,如切如磋,如琢如磨。","I am just joking."])
}
typedJSFn.run(subtitleType)</script><script>(() => {
const parseViewBox = viewBox => {
if (!viewBox) return null
const parts = viewBox.trim().split(/[\s,]+/).map(n => Number(n))
if (parts.length !== 4 || parts.some(n => Number.isNaN(n))) return null
return parts
}
const getSvgViewBox = svg => {
const attr = parseViewBox(svg.getAttribute('viewBox'))
if (attr) return attr
// Fallback: use bbox to build a viewBox
try {
const bbox = svg.getBBox()
if (bbox && bbox.width && bbox.height) return [bbox.x, bbox.y, bbox.width, bbox.height]
} catch (e) {
// getBBox may fail on some edge cases; ignore
}
const w = Number(svg.getAttribute('width')) || 0
const h = Number(svg.getAttribute('height')) || 0
if (w > 0 && h > 0) return [0, 0, w, h]
return [0, 0, 100, 100]
}
const setSvgViewBox = (svg, vb) => {
svg.setAttribute('viewBox', `${vb[0]} ${vb[1]} ${vb[2]} ${vb[3]}`)
}
const clamp = (v, min, max) => Math.max(min, Math.min(max, v))
const openSvgInNewTab = ({ source, initViewBox }) => {
const getClonedSvg = () => {
if (typeof source === 'string') {
const template = document.createElement('template')
template.innerHTML = source.trim()
const svg = template.content.querySelector('svg')
return svg ? svg.cloneNode(true) : null
}
if (source && typeof source.cloneNode === 'function') {
return source.cloneNode(true)
}
return null
}
const clone = getClonedSvg()
if (!clone) return
if (initViewBox && initViewBox.length === 4) {
clone.setAttribute('viewBox', initViewBox.join(' '))
}
if (!clone.getAttribute('xmlns')) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
if (!clone.getAttribute('xmlns:xlink') && clone.innerHTML.includes('xlink:')) {
clone.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink')
}
// inject background to match current theme
const isDark = document.documentElement.getAttribute('data-theme') === 'dark'
const bg = getComputedStyle(document.body).backgroundColor || (isDark ? '#1e1e1e' : '#ffffff')
if (!clone.style.background) clone.style.background = bg
const serializer = new XMLSerializer()
const svgSource = serializer.serializeToString(clone)
const htmlSource = `<!doctype html><html><head><meta charset="utf-8" />
<style>
html, body { width: 100%; height: 100%; margin: 0; display: flex; align-items: center; justify-content: center; background: ${bg}; }
svg { max-width: 100%; max-height: 100%; height: auto; width: auto; }
</style>
</head><body>${svgSource}</body></html>`
const blob = new Blob([htmlSource], { type: 'text/html;charset=utf-8' })
const url = URL.createObjectURL(blob)
window.open(url, '_blank', 'noopener')
setTimeout(() => URL.revokeObjectURL(url), 5000)
}
const attachMermaidViewerButton = wrap => {
let btn = wrap.querySelector('.mermaid-open-btn')
if (!btn) {
btn = document.createElement('button')
btn.type = 'button'
btn.className = 'mermaid-open-btn'
wrap.appendChild(btn)
}
btn.innerHTML = '<i class="fa fa-search fa-fw" aria-hidden="true"></i>'
if (!btn.__mermaidViewerBound) {
btn.addEventListener('click', e => {
e.preventDefault()
e.stopPropagation()
const svg = wrap.__mermaidOriginalSvg || wrap.querySelector('svg')
if (!svg) return
const initViewBox = wrap.__mermaidInitViewBox
openSvgInNewTab({ source: svg, initViewBox })
})
btn.__mermaidViewerBound = true
}
}
// Zoom around a point (px, py) in the SVG viewport (in viewBox coordinates)
const zoomAtPoint = (vb, factor, px, py) => {
const w = vb[2] * factor
const h = vb[3] * factor
const nx = px - (px - vb[0]) * factor
const ny = py - (py - vb[1]) * factor
return [nx, ny, w, h]
}
const initMermaidGestures = wrap => {
// Clean up previous event listeners and pending frames
if (wrap.__mermaidAbortController) {
wrap.__mermaidAbortController.abort()
if (wrap.__mermaidRafId) cancelAnimationFrame(wrap.__mermaidRafId)
}
const ac = new AbortController()
wrap.__mermaidAbortController = ac
const svg = wrap.querySelector('svg')
if (!svg) return
// Ensure viewBox exists so gestures always work
const initVb = getSvgViewBox(svg)
wrap.__mermaidInitViewBox = initVb
wrap.__mermaidCurViewBox = initVb.slice()
setSvgViewBox(svg, initVb)
// Disable default gestures to prevent scroll chaining and pinch-zoom penetration in Chrome
svg.style.touchAction = 'none'
// Cache BoundingClientRect, throttled on scroll to reduce reflow
let cachedRect = svg.getBoundingClientRect()
let rectDirty = false
const markRectDirty = () => { rectDirty = true }
window.addEventListener('resize', markRectDirty, { signal: ac.signal })
window.addEventListener('scroll', markRectDirty, { signal: ac.signal, capture: true })
const getRect = () => {
if (rectDirty) {
cachedRect = svg.getBoundingClientRect()
rectDirty = false
}
return cachedRect
}
// Precompute clamp bounds from initial viewBox
const minW = initVb[2] * 0.1
const maxW = initVb[2] * 10
const minH = initVb[3] * 0.1
const maxH = initVb[3] * 10
const clampVb = vb => {
const out = vb.slice()
out[2] = clamp(out[2], minW, maxW)
out[3] = clamp(out[3], minH, maxH)
return out
}
// Throttle DOM updates using requestAnimationFrame
let pendingVb = null
let rafId = null
const applyVb = () => {
if (pendingVb) {
wrap.__mermaidCurViewBox = pendingVb
setSvgViewBox(svg, pendingVb)
pendingVb = null
}
rafId = null
wrap.__mermaidRafId = null
}
const setCurVb = vb => {
pendingVb = clampVb(vb)
if (!rafId) {
rafId = requestAnimationFrame(applyVb)
wrap.__mermaidRafId = rafId
}
}
const state = {
pointers: new Map(),
startVb: null,
startDist: 0,
lastPointerX: 0,
lastPointerY: 0
}
const onPointerDown = e => {
if (e.pointerType === 'mouse' && e.button !== 0) return
svg.setPointerCapture(e.pointerId)
const curVb = wrap.__mermaidCurViewBox
state.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
if (state.pointers.size === 1) {
state.startVb = curVb.slice()
state.lastPointerX = e.clientX
state.lastPointerY = e.clientY
} else if (state.pointers.size === 2) {
const pts = [...state.pointers.values()]
const dx = pts[0].x - pts[1].x
const dy = pts[0].y - pts[1].y
state.startDist = Math.hypot(dx, dy)
state.startVb = curVb.slice()
}
}
const onPointerMove = e => {
if (!state.pointers.has(e.pointerId)) return
state.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
const curVb = wrap.__mermaidCurViewBox
const rect = getRect()
if (state.pointers.size === 1 && state.startVb) {
const p = state.pointers.values().next().value
const dxClient = p.x - state.lastPointerX
const dyClient = p.y - state.lastPointerY
state.lastPointerX = p.x
state.lastPointerY = p.y
const dx = dxClient * (curVb[2] / rect.width)
const dy = dyClient * (curVb[3] / rect.height)
setCurVb([curVb[0] - dx, curVb[1] - dy, curVb[2], curVb[3]])
return
}
if (state.pointers.size === 2 && state.startVb && state.startDist > 0) {
const pts = [...state.pointers.values()]
const dx = pts[0].x - pts[1].x
const dy = pts[0].y - pts[1].y
const dist = Math.hypot(dx, dy)
if (!dist) return
const factor = state.startDist / dist
const cx = (pts[0].x + pts[1].x) / 2
const cy = (pts[0].y + pts[1].y) / 2
const px = curVb[0] + (cx - rect.left) * (curVb[2] / rect.width)
const py = curVb[1] + (cy - rect.top) * (curVb[3] / rect.height)
setCurVb(zoomAtPoint(state.startVb, factor, px, py))
}
}
const onPointerUpOrCancel = e => {
// Release PointerCapture to avoid event capture anomalies
if (svg.hasPointerCapture && svg.hasPointerCapture(e.pointerId)) {
svg.releasePointerCapture(e.pointerId)
}
state.pointers.delete(e.pointerId)
if (state.pointers.size === 0) {
state.startVb = null
state.startDist = 0
} else if (state.pointers.size === 1) {
const p = state.pointers.values().next().value
state.lastPointerX = p.x
state.lastPointerY = p.y
}
}
const onWheel = e => {
// Prevent event bubbling from triggering external scroll
e.preventDefault()
e.stopPropagation()
// Normalize deltaY across deltaMode (Chrome uses pixels, Safari uses lines)
let delta = e.deltaY
if (e.deltaMode === 1) delta *= 16
else if (e.deltaMode === 2) delta *= 400
// Continuous zoom factor: smoother than fixed 1.1/0.9 steps
const zoomFactor = Math.pow(1.001, delta)
const curVb = wrap.__mermaidCurViewBox
const rect = getRect()
const px = curVb[0] + (e.clientX - rect.left) * (curVb[2] / rect.width)
const py = curVb[1] + (e.clientY - rect.top) * (curVb[3] / rect.height)
setCurVb(zoomAtPoint(curVb, zoomFactor, px, py))
}
const onDblClick = () => {
const init = wrap.__mermaidInitViewBox
if (init) setCurVb(init)
}
svg.addEventListener('pointerdown', onPointerDown, { signal: ac.signal })
svg.addEventListener('pointermove', onPointerMove, { signal: ac.signal })
svg.addEventListener('pointerup', onPointerUpOrCancel, { signal: ac.signal })
svg.addEventListener('pointercancel', onPointerUpOrCancel, { signal: ac.signal })
svg.addEventListener('wheel', onWheel, { passive: false, signal: ac.signal })
svg.addEventListener('dblclick', onDblClick, { signal: ac.signal })
}
const runMermaid = ele => {
window.loadMermaid = true
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default'
ele.forEach((item, index) => {
const mermaidSrc = item.firstElementChild
// Clean up event listeners before removing old SVG
if (item.__mermaidAbortController) {
item.__mermaidAbortController.abort()
}
const oldSvg = item.querySelector('svg')
if (oldSvg) oldSvg.remove()
let config = {}
try {
config = mermaidSrc.dataset.config ? JSON.parse(mermaidSrc.dataset.config) : {}
} catch (e) {
console.warn('[mermaid] failed to parse dataset.config:', e)
}
if (!config.theme) {
config.theme = theme
}
const mermaidThemeConfig = `%%{init: ${JSON.stringify(config)}}%%\n`
const mermaidID = `mermaid-${index}`
const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
const renderMermaid = svg => {
mermaidSrc.insertAdjacentHTML('afterend', svg)
if (true) initMermaidGestures(item)
item.__mermaidOriginalSvg = svg
if (true) attachMermaidViewerButton(item)
}
const handleError = err => {
console.error(`[mermaid] render failed for block #${index}:`, err)
const errorEl = document.createElement('div')
errorEl.className = 'mermaid-error'
errorEl.textContent = `Mermaid render error: ${err.message || err}`
mermaidSrc.insertAdjacentElement('afterend', errorEl)
}
try {
const renderFn = mermaid.render(mermaidID, mermaidDefinition)
// mermaid v9 and v10 compatibility
if (typeof renderFn === 'string') {
renderMermaid(renderFn)
} else {
renderFn.then(({ svg }) => renderMermaid(svg)).catch(handleError)
}
} catch (err) {
handleError(err)
}
})
}
const codeToMermaid = $article => {
const codeMermaidEle = $article.querySelectorAll('pre > code.mermaid')
if (codeMermaidEle.length === 0) return
codeMermaidEle.forEach(ele => {
const preEle = document.createElement('pre')
preEle.className = 'mermaid-src'
preEle.hidden = true
preEle.textContent = ele.textContent
const newEle = document.createElement('div')
newEle.className = 'mermaid-wrap'
newEle.appendChild(preEle)
ele.parentNode.replaceWith(newEle)
})
}
const loadMermaid = () => {
const $article = document.getElementById('article-container')
if (!$article) return
if (true) codeToMermaid($article)
const $mermaid = $article.querySelectorAll('.mermaid-wrap')
if ($mermaid.length === 0) return
const runMermaidFn = () => runMermaid($mermaid)
btf.addGlobalFn('themeChange', runMermaidFn, 'mermaid')
window.loadMermaid ? runMermaidFn() : btf.getScript('https://cdn.jsdelivr.net/npm/mermaid@11.16.0/dist/mermaid.min.js').then(runMermaidFn)
}
btf.addGlobalFn('encrypt', loadMermaid, 'mermaid')
window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
})()</script></div><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1.1.6/dist/canvas-fluttering-ribbon.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1.1.6/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script src="https://cdn.jsdelivr.net/npm/pjax@0.2.8/pjax.min.js" defer="defer"></script><script>document.addEventListener('DOMContentLoaded', () => {
const pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]
window.pjax = new Pjax({
elements: 'a:not([target="_blank"]):not([data-fancybox])',
selectors: pjaxSelectors,
cacheBust: false,
analytics: false,
scrollRestoration: false
})
const triggerPjaxFn = (val) => {
if (!val) return
Object.values(val).forEach(fn => {
try {
fn()
} catch (err) {
console.debug('Pjax callback failed:', err)
}
})
}
document.addEventListener('pjax:send', () => {
// removeEventListener
btf.removeGlobalFnEvent('pjaxSendOnce')
btf.removeGlobalFnEvent('themeChange')
// reset readmode
const $bodyClassList = document.body.classList
if ($bodyClassList.contains('read-mode')) $bodyClassList.remove('read-mode')
triggerPjaxFn(window.globalFn.pjaxSend)
})
document.addEventListener('pjax:complete', () => {
btf.removeGlobalFnEvent('pjaxCompleteOnce')
document.querySelectorAll('script[data-pjax]').forEach(item => {
if (!item.parentNode) return
const newScript = document.createElement('script')
const content = item.text || item.textContent || ''
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
newScript.appendChild(document.createTextNode(content))
item.parentNode.replaceChild(newScript, item)
})
triggerPjaxFn(window.globalFn.pjaxComplete)
})
document.addEventListener('pjax:error', e => {
const responseURL = e.request && e.request.responseURL
if (e.request && e.request.status === 404) {
true
? pjax.loadUrl('/404.html')
: responseURL && (window.location.href = responseURL)
} else if (responseURL) {
window.location.href = responseURL
}
})
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">Search</span><i class="fas fa-spinner fa-pulse" id="loading-status" hidden="hidden"></i><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="text-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span> Loading Database</span></div><div class="local-search-input"><input placeholder="搜索文章..." type="text"/></div><hr/><div id="local-search-results"></div><div class="ais-Pagination" id="local-search-pagination" style="display:none;"><ul class="ais-Pagination-list"></ul></div><div id="local-search-stats"></div></div><div id="search-mask"></div><script src="/js/search/local-search.js?v=5.7.0"></script></div></div></body></html>