PageSourceSearch

https://perfectplay.dev/omega-2

html perfectplay.dev collected 2026-10-02 01:52:29 UTC 16,353 bytes, 581 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="UTF-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6  <title>Omega II Blackjack Calculator | PerfectPlay</title>
7  <meta name="description" content="Omega II blackjack calculator. Ace-neutral level-two card counting assistant with live stats and betting ramp.">
8  <link rel="canonical" href="https://perfectplay.dev/omega-2">
9
10  <!-- JSON-LD Structured Schema -->
11  
11<script type="application/ld+json">
12  {
13    "@context": "https://schema.org",
14    "@type": "SoftwareApplication",
15    "name": "Omega II Blackjack Calculator",
16    "url": "https://perfectplay.dev/omega-2",
17    "description": "Omega II blackjack calculator. Ace-neutral level-two card counting assistant with live stats and betting ramp.",
18    "applicationCategory": "GameApplication",
19    "operatingSystem": "All"
20  }
21  </script>
21
22
23  <link rel="preconnect" href="https://fonts.googleapis.com">
24  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
25  <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;600;700;800&family=Source+Code+Pro:wght@300;400;500;600;700&display=swap" rel="stylesheet">
26  <link rel="stylesheet" href="style.css">
27  <style>
28    :root {
29      --bg1: #7a0000;
30      --bg2: #b00000;
31      --card: rgba(255,255,255,0.12);
32      --card-border: rgba(255,255,255,0.18);
33      --text: #fff7f7;
34      --muted: rgba(255,247,247,0.78);
35      --accent: #ffd9d9;
36      --shadow: 0 10px 30px rgba(0,0,0,0.22);
37    }
38    
39    body {
40      margin: 0;
41      padding: 0;
42      background: #000;
43      font-family: Arial, sans-serif;
44      color: var(--text);
45      background: linear-gradient(135deg, var(--bg1), var(--bg2));
46      min-height: 100vh;
47      box-sizing: border-box;
48      padding-top: 90px;
49    }
50
51    .o2-wrap {
52      max-width: 1100px;
53      margin: 0 auto;
54      padding: 18px;
55    }
56
57    .o2-header {
58      display: flex;
59      justify-content: space-between;
60      align-items: flex-start;
61      gap: 12px;
62      margin-bottom: 16px;
63    }
64
65    .o2-title {
66      font-size: 28px;
67      font-weight: 700;
68      line-height: 1.1;
69      margin: 0;
70    }
71
72    .o2-sub {
73      font-size: 14px;
74      color: var(--muted);
75      margin-top: 6px;
76    }
77
78    .o2-row {
79      display: grid;
80      grid-template-columns: repeat(2, minmax(0,1fr));
81      gap: 10px;
82    }
83
84    .o2-field {
85      display: flex;
86      flex-direction: column;
87      gap: 6px;
88      margin-bottom: 10px;
89    }
90
91    label {
92      font-size: 12px;
93      color: var(--muted);
94      font-weight: 700;
95    }
96
97    input, select, textarea, button {
98      font: inherit;
99    }
100
101    input, select, textarea {
102      width: 100%;
103      padding: 10px 12px;
104      border-radius: 12px;
105      border: 1px solid rgba(255,255,255,0.18);
106      background: rgba(255,255,255,0.96);
107      color: #2b0000;
108      outline: none;
109    }
110
111    textarea {
112      min-height: 110px;
113      resize: vertical;
114    }
115
116    .o2-actions {
117      display: flex;
118      flex-wrap: wrap;
119      gap: 10px;
120      margin-top: 10px;
121    }
122
123    button {
124      border: 0;
125      border-radius: 12px;
126      padding: 10px 14px;
127      cursor: pointer;
128      background: #fff;
129      color: #7a0000;
130      font-weight: 700;
131    }
132
133    button.o2-secondary {
134      background: rgba(255,255,255,0.18);
135      color: var(--text);
136      border: 1px solid rgba(255,255,255,0.18);
137    }
138
139    .o2-preset-btns {
140      display: flex;
141      flex-wrap: wrap;
142      gap: 8px;
143      margin-bottom: 8px;
144    }
145
146    .o2-preset-btns button {
147      padding: 6px 12px;
148      font-size: 12px;
149      background: rgba(255,255,255,0.18);
150      color: var(--text);
151      border: 1px solid rgba(255,255,255,0.28);
152      border-radius: 999px;
153      font-weight: 700;
154      cursor: pointer;
155    }
156
157    .o2-preset-btns button:hover {
158      background: rgba(255,255,255,0.30);
159    }
160
161    .o2-stats {
162      display: grid;
163      grid-template-columns: repeat(3, minmax(0,1fr));
164      gap: 10px;
165    }
166
167    .o2-stat {
168      background: rgba(255,255,255,0.09);
169      border: 1px solid rgba(255,255,255,0.14);
170      border-radius: 14px;
171      padding: 14px;
172    }
173
174    .o2-stat .k {
175      font-size: 12px;
176      color: var(--muted);
177      margin-bottom: 6px;
178      font-weight: 700;
179    }
180
181    .o2-stat .v {
182      font-size: 24px;
183      font-weight: 700;
184      line-height: 1;
185    }
186
187    .o2-note {
188      margin-top: 12px;
189      font-size: 12px;
190      color: var(--muted);
191      line-height: 1.45;
192    }
193
194    .o2-tags {
195      display: flex;
196      flex-wrap: wrap;
197      gap: 8px;
198      margin-top: 8px;
199      justify-content: flex-end;
200    }
201
202    .o2-tag {
203      font-size: 12px;
204      background: rgba(255,255,255,0.12);
205      border: 1px solid rgba(255,255,255,0.12);
206      border-radius: 999px;
207      padding: 5px 8px;
208      color: var(--accent);
209    }
210
211    .o2-divider {
212      height: 1px;
213      background: rgba(255,255,255,0.14);
214      margin: 14px 0;
215    }
216
217    .o2-full {
218      grid-column: 1 / -1;
219    }
220
221    .o2-chart-label {
222      font-size: 11px;
223      font-weight: 700;
224      color: var(--muted);
225      letter-spacing: 0.06em;
226      text-transform: uppercase;
227      margin-bottom: 6px;
228      margin-top: 14px;
229    }
230
231    .o2-tc-svg {
232      width: 100%;
233      display: block;
234    }
235
236    .o2-dist-legend {
237      display: flex;
238      gap: 14px;
239      margin-bottom: 8px;
240      flex-wrap: wrap;
241    }
242
243    .o2-dist-legend span {
244      font-size: 11px;
245      color: var(--muted);
246      display: flex;
247      align-items: center;
248      gap: 5px;
249    }
250
251    .o2-dist-legend i {
252      display: inline-block;
253      width: 10px;
254      height: 10px;
255      border-radius: 2px;
256      flex-shrink: 0;
257    }
258
259    .o2-bar-wrap {
260      display: flex;
261      align-items: flex-end;
262      gap: 5px;
263      height: 130px;
264      margin-top: 4px;
265    }
266
267    .o2-bar-col {
268      display: flex;
269      flex-direction: column;
270      align-items: center;
271      flex: 1;
272      height: 100%;
273      justify-content: flex-end;
274      gap: 2px;
275    }
276
277    .o2-bar {
278      width: 100%;
279      border-radius: 4px 4px 0 0;
280      min-height: 2px;
281    }
282
283    .o2-bar-lbl {
284      font-size: 10px;
285      color: var(--muted);
286    }
287
288    .o2-bar-pct {
289      font-size: 10px;
290      font-weight: 700;
291      color: var(--text);
292      line-height: 1.2;
293    }
294
295    .o2-bar-cnt {
296      font-size: 9px;
297      color: var(--muted);
298      line-height: 1.2;
299    }
300
301    .o2-no-data {
302      font-size: 13px;
303      color: var(--muted);
304      padding: 10px 0;
305    }
306
307    .o2-approx-note {
308      font-size: 11px;
309      color: var(--muted);
310      margin-bottom: 8px;
311    }
312
313    @media (max-width: 900px) {
314      .o2-header {
315        align-items: flex-start;
316        flex-direction: column;
317      }
318      .o2-tags {
319        justify-content: flex-start;
320      }
321    }
322
323    @media (max-width: 640px) {
324      .o2-row, .o2-stats {
325        grid-template-columns: 1fr;
326      }
327      .o2-title {
328        font-size: 24px;
329      }
330    }
331
332    /* Draggable Collapsible Block Styles */
333    .blocks-container {
334      display: flex;
335      flex-direction: column;
336      gap: 16px;
337      margin-top: 16px;
338    }
339
340    .drag-block {
341      background: var(--card);
342      border: 1px solid var(--card-border);
343      border-radius: 16px;
344      box-shadow: var(--shadow);
345      backdrop-filter: blur(4px);
346      transition: opacity 0.2s ease, transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
347    }
348
349    .drag-block.dragging {
350      opacity: 0.4;
351      transform: scale(0.98);
352      border: 2px dashed rgba(255, 255, 255, 0.4);
353    }
354
355    .drag-block.drag-over {
356      border-color: #ffd9d9;
357      box-shadow: 0 0 15px rgba(255, 217, 217, 0.3);
358    }
359
360    .block-header {
361      display: flex;
362      align-items: center;
363      padding: 14px 18px;
364      border-bottom: 1px solid rgba(255, 255, 255, 0.08);
365      user-select: none;
366    }
367
368    .block-header.collapsible {
369      cursor: pointer;
370    }
371
372    .block-header h3 {
373      margin: 0;
374      font-size: 16px;
375      font-weight: 700;
376      flex: 1;
377    }
378
379    .drag-handle {
380      font-size: 18px;
381      color: var(--muted);
382      cursor: grab;
383      margin-right: 12px;
384      padding: 0 4px;
385    }
386
387    .drag-handle:active {
388      cursor: grabbing;
389    }
390
391    .collapse-toggle {
392      font-size: 10px;
393      color: var(--muted);
394      transition: transform 0.2s ease;
395      margin-left: 10px;
396    }
397
398    .block-header.collapsed .collapse-toggle {
399      transform: rotate(-90deg);
400    }
401
402    .block-header.collapsed {
403      border-bottom-color: transparent;
404    }
405
406    .block-content {
407      padding: 18px;
408      overflow: hidden;
409    }
410
411    .block-content.collapsed {
412      display: none;
413    }
414  </style>
415</head>
416<body>
417
418  <!-- ===== NAVIGATION ===== -->
419  <header class="site-header" id="top">
420    <nav class="nav-inner">
421      <a href="/" class="logo" aria-label="PerfectPlay Home">
422        <span class="logo-text">PerfectPlay</span>
423      </a>
424      <button class="hamburger" id="hamburger" aria-label="Toggle menu" aria-expanded="false">
425        <span></span><span></span><span></span>
426      </button>
427      <ul class="nav-links" id="nav-links">
428        <li><a href="/" class="nav-link">HOME</a></li>
429        <li><a href="/wong-halves" class="nav-link">WONG HALVES</a></li>
430        <li><a href="/omega-2" class="nav-link active">OMEGA 2</a></li>
431        <li><a href="/hi-opt-ii" class="nav-link">HI OPT II</a></li>
432        <li><a href="/hi-lo" class="nav-link">HI-LO</a></li>
433        <li><a href="/zen" class="nav-link">ZEN COUNT</a></li>
434        <li class="nav-dropdown-wrap">
435          <button class="more-btn" aria-label="More options">
436            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
437              <circle cx="12" cy="12" r="1"></circle>
438              <circle cx="19" cy="12" r="1"></circle>
439              <circle cx="5" cy="12" r="1"></circle>
440            </svg>
441          </button>
442          <ul class="dropdown-menu">
443            <li><a href="/wong-halves">WONG HALVES</a></li>
444            <li><a href="/omega-2">OMEGA 2</a></li>
445            <li><a href="/hi-opt-ii">HI OPT II</a></li>
446            <li><a href="/hi-lo">HI-LO</a></li>
447            <li><a href="/zen">ZEN COUNT</a></li>
448            <li><a href="/full-composition">FULL COMPOSITION</a></li>
449            <li><a href="/privacy">Privacy Policy</a></li>
450            <li class="dropdown-divider" style="border-top: 1px solid rgba(255,255,255,0.1); margin: 6px 0;"></li>
451            <li><a href="/" style="font-weight: 600; color: #fff;">English</a></li>
452            <li><a href="/zh">中文 (Mandarin)</a></li>
453            <li><a href="/fr">Français</a></li>
454            <li><a href="/ru">Русский</a></li>
455          </ul>
456        </li>
457      </ul>
458    </nav>
459  </header>
460<body>
461
462  <div class="o2-wrap">
463    <!-- Header -->
464    <div class="o2-header">
465      <div>
466        <h2 class="o2-title">Omega II Assistant</h2>
467        <div class="o2-sub">Ace-neutral level-two count. Betting uses granular betting TC rather than rounded TC for better accuracy. Rounded TC is displayed only as an extra reference.</div>
468      </div>
469      <div class="o2-tags">
470        <span class="o2-tag">T/J/Q/K:-2</span>
471        <span class="o2-tag">A:0 side</span>
472      </div>
473    </div>
474
475    <!-- Draggable Collapsible Blocks Container -->
476    <div class="blocks-container" id="blocks-container">
477      
478      <!-- Card Entry Block -->
479      <div class="drag-block" draggable="true" data-block-id="card-entry" id="block-card-entry">
480        <div class="block-header">
481          <span class="drag-handle">&#9776;</span>
482          <h3>Card Entry</h3>
483        </div>
484        <div class="block-content">
485          <div class="o2-field">
486            <label for="o2-cards">Cards seen</label>
487            <input id="o2-cards" type="text" placeholder="Example: 2 5 A T 9">
488          </div>
489          <div class="o2-row">
490            <div class="o2-field">
491              <label for="o2-decksTotal">Number of decks</label>
492              <input id="o2-decksTotal" type="number" min="1" max="12" step="1">
493            </div>
494            <div class="o2-field">
495              <label for="o2-shuffleAt">Shuffle when decks remaining &lt;=</label>
496              <input id="o2-shuffleAt" type="number" min="0" step="0.1">
497            </div>
498          </div>
499          <div class="o2-actions">
500            <button id="o2-add">Add</button>
501            <button id="o2-undo" class="o2-secondary">Undo last add</button>
502            <button id="o2-reset" class="o2-secondary">New shoe</button>
503          </div>
504          <div class="o2-note">10 becomes T. Aces are side-counted and used only for betting true count adjustment.</div>
505        </div>
506      </div>
507
508      <!-- Live Stats Block -->
509      <div class="drag-block" draggable="true" data-block-id="live-stats" id="block-live-stats">
510        <div class="block-header collapsible" id="header-live-stats">
511          <span class="drag-handle">&#9776;</span>
512          <h3>Live Stats</h3>
513          <span class="collapse-toggle">&#9660;</span>
514        </div>
515        <div class="block-content" id="content-live-stats">
516          <div class="o2-stats">
517            <div class="o2-stat"><div class="k">Running count</div><div class="v" id="o2-rc"></div></div>
518            <div class="o2-stat"><div class="k">Ace side count</div><div class="v" id="o2-asc"></div></div>
519            <div class="o2-stat"><div class="k">Decks remaining</div><div class="v" id="o2-dr"></div></div>
520            <div class="o2-stat"><div class="k">Main true count</div><div class="v" id="o2-mtc"></div></div>
521            <div class="o2-stat"><div class="k">Ace adjustment</div><div class="v" id="o2-aa"></div></div>
522            <div class="o2-stat"><div class="k">Betting true count</div><div class="v" id="o2-tc"></div></div>
523            <div class="o2-stat"><div class="k">Rounded TC</div><div class="v" id="o2-tcr"></div></div>
524          </div>
525        </div>
526      </div>
527
528      <!-- Relevant Settings Block -->
529      <div class="drag-block" draggable="true" data-block-id="relevant-settings" id="block-relevant-settings">
530        <div class="block-header collapsible" id="header-relevant-settings">
531          <span class="drag-handle">&#9776;</span>
532          <h3>Relevant Settings</h3>
533          <span class="collapse-toggle">&#9660;</span>
534        </div>
535        <div class="block-content" id="content-relevant-settings">
536          <div class="o2-row">
537            <div class="o2-field">
538              <label for="o2-tableMin">Table minimum</label>
539              <input id="o2-tableMin" type="number" min="1" step="1">
540            </div>
541            <div class="o2-field">
542              <label for="o2-tableMax">Table maximum</label>
543              <input id="o2-tableMax" type="number" min="1" step="1">
544            </div>
545          </div>
546          <div class="o2-field">
547            <label for="o2-insuranceIndex">Insurance index</label>
548            <input id="o2-insuranceIndex" type="number" step="0.5">
549          </div>
550          <div class="o2-field">
551            <label>How much to bet at each true count level</label>
552            <div class="o2-preset-btns">
553              <button id="o2-preset-1-8">Spread 1-8</button>
554              <button id="o2-preset-1-12">Spread 1-12</button>
555              <button id="o2-preset-1-16">Spread 1-16</button>
556            </div>
557            <textarea id="o2-customRamp"></textarea>
558          </div>
559          <div class="o2-note">Edit directly or tap a preset above to load it. Each line: TC&lt;=0:1, TC&gt;=1:2, TC&gt;=4:12 etc. Insurance uses main true count. Betting uses ace-adjusted true count.</div>
560        </div>
561      </div>
562
563      <!-- History Stats Block -->
564      <div class="drag-block" draggable="true" data-block-id="history-stats" id="block-history-stats">
565        <div class="block-header collapsible" id="header-history-stats">
566          <span class="drag-handle">&#9776;</span>
567          <h3>History &amp; Stats</h3>
568          <span class="collapse-toggle">&#9660;</span>
569        </div>
570        <div class="block-content" id="content-history-stats">
571          <div id="o2-history-body"></div>
572        </div>
573      </div>
574
575    </div>
576  </div>
577
578  
578<script src="main.js"></script>
578
579  
579<script src="omega-2.js"></script>
579
580</body>
581</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.