#tvm-mag section,#tvm-mag article,#tvm-mag main{display:block !important;float:none !important;vertical-align:top} #tvm-mag section,#tvm-mag article{max-width:none;min-width:0} #tvm-mag{font-family:var(--f-body) !important;font-weight:400 !important} #tvm-mag{letter-spacing:normal !important;text-transform:none !important} #tvm-mag{max-width:none !important;box-sizing:border-box} #tvm-mag main,#tvm-mag main>section,#tvm-mag main>div{max-width:none !important;float:none !important} #tvm-mag *{font-family:inherit !important;font-variant-caps:normal !important;font-weight:inherit !important;letter-spacing:inherit !important;text-transform:inherit !important} #tvm-mag strong,#tvm-mag b{font-weight:700 !important} /* Chống theme ép font/kiểu chữ lên p, li */ #tvm-mag p,#tvm-mag li,#tvm-mag blockquote,#tvm-mag figcaption{font-family:var(--f-body) !important;text-transform:none !important;font-variant:normal !important;font-feature-settings:normal !important} #tvm-mag p.issue{text-transform:uppercase !important} #tvm-mag *{font-variant-caps:normal !important} #tvm-mag span,#tvm-mag a,#tvm-mag strong,#tvm-mag em,#tvm-mag b,#tvm-mag i,#tvm-mag small{font-family:inherit !important;text-transform:inherit !important} /* ========================================================= eMagazine TrangVM x ISTQB CT-AI | style gói trong #tvm-mag ========================================================= */ #tvm-mag{ --blue:#1F6BFF;--blue-2:#3FA4FF;--sky:#8FD8FF;--sky-2:#CDEEFF; --deep:#0F2A8F;--ink:#0D1B4C;--muted:#45527E; --cloud:#F3F8FF;--cloud-2:#E1EEFF;--sun:#FFD23F;--pink:#FF6FA3;--mint:#6FE3C8; --line:rgba(13,27,76,.14); --f-display:'Bricolage Grotesque',system-ui,sans-serif; --f-poem:'Fraunces',Georgia,serif; --f-body:'Be Vietnam Pro',system-ui,sans-serif; --bar-h:64px;--foot-h:56px;--r:22px; position:relative;background:var(--cloud);color:var(--ink); font-family:var(--f-body) !important;font-size:16px !important;line-height:1.65 !important;-webkit-font-smoothing:antialiased; overflow-wrap:normal;word-break:normal;text-align:left !important;hyphens:manual; } /* Chống CSS theme WordPress */ #tvm-mag main{display:block;container-type:inline-size} #tvm-mag h1,#tvm-mag h2,#tvm-mag h3,#tvm-mag p,#tvm-mag li,#tvm-mag dt,#tvm-mag dd,#tvm-mag dl,#tvm-mag blockquote,#tvm-mag cite,#tvm-mag figure,#tvm-mag figcaption,#tvm-mag mark{color:inherit;font-family:inherit;font-size:inherit !important;line-height:inherit !important;letter-spacing:inherit !important;text-transform:none !important;font-style:normal !important;margin:0;padding:0;border:0;background:none;box-shadow:none;text-align:left !important;quotes:none} #tvm-mag h1,#tvm-mag h2,#tvm-mag h3{font-weight:700 !important;clear:none} #tvm-mag span,#tvm-mag i,#tvm-mag b,#tvm-mag strong,#tvm-mag em,#tvm-mag small{font-family:inherit;letter-spacing:inherit !important;text-transform:inherit !important;line-height:inherit !important;color:inherit;font-style:normal !important;margin:0;padding:0;border:0;background:none} #tvm-mag b,#tvm-mag strong{font-weight:700 !important} #tvm-mag blockquote::before,#tvm-mag blockquote::after,#tvm-mag h2::before,#tvm-mag h2::after,#tvm-mag h3::before,#tvm-mag h3::after,#tvm-mag li::before,#tvm-mag li::after{content:none;display:none} #tvm-mag ol,#tvm-mag ul{list-style:none;margin:0;padding:0} #tvm-mag li{list-style:none} #tvm-mag button{background:none;border:0;border-radius:0;box-shadow:none;margin:0;padding:0;min-width:0;min-height:0;height:auto;width:auto;font:inherit;color:inherit;letter-spacing:inherit !important;text-transform:none !important;line-height:inherit !important;text-shadow:none;cursor:pointer;touch-action:manipulation} #tvm-mag a{box-shadow:none;border:0;text-decoration:none;color:inherit} #tvm-mag img{border:0;border-radius:0;box-shadow:none;margin:0;padding:0;max-width:none} #tvm-mag svg{max-width:none} #tvm-mag *,#tvm-mag *::before,#tvm-mag *::after{box-sizing:border-box} #tvm-mag :focus-visible{outline:3px solid var(--sun);outline-offset:3px} .row:has(#tvm-mag) > .jeg_sidebar{display:none !important} .row:has(#tvm-mag) > .jeg_main_content{width:100% !important;max-width:100% !important;flex:0 0 100% !important} html.tvm-immersive .jeg_stickybar,html.tvm-immersive .jeg_navbar_mobile_wrapper .jeg_sticky_nav{visibility:hidden !important} #tvm-mag .lbl{font-family:var(--f-display) !important;font-weight:600 !important;font-size:12px !important;letter-spacing:.08em !important;text-transform:uppercase !important;line-height:1.4 !important} #tvm-mag .poem{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:300 !important} /* ---------- Thanh trên & dưới ---------- */ #tvm-mag .topbar{position:fixed;left:0;right:0;top:var(--top,0px);height:var(--bar-h);z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease-out,visibility .3s; display:flex;align-items:flex-start;gap:16px;padding:16px 20px;color:#fff;mix-blend-mode:difference;pointer-events:none} #tvm-mag .topbar > *{pointer-events:auto} #tvm-mag.bars-on .topbar,#tvm-mag.bars-on .progress{opacity:1;visibility:visible} #tvm-mag .icon-btn{width:44px;height:44px;margin:-8px 0 0 -8px;display:grid;place-items:center} #tvm-mag .icon-btn span{display:block;width:18px;height:14px;border:1.5px solid currentColor;border-left:0;border-right:0;position:relative} #tvm-mag .icon-btn span::after{content:"";position:absolute;left:0;right:0;top:50%;border-top:1.5px solid currentColor;transform:translateY(-50%)} #tvm-mag .issue{font-family:var(--f-display) !important;font-weight:600 !important;font-size:11px !important;letter-spacing:.08em !important;text-transform:uppercase !important;line-height:1.45 !important} #tvm-mag .all-btn{margin-left:auto;height:30px;padding:0 14px;border:1px solid currentColor;border-radius:999px;display:flex;align-items:center;gap:8px;font-family:var(--f-display) !important;font-weight:600 !important;font-size:12px !important} #tvm-mag .all-btn i{display:inline-flex;gap:2px} #tvm-mag .all-btn i b{width:4px;height:8px;background:currentColor;border-radius:2px} #tvm-mag .progress{position:fixed;left:0;right:0;bottom:0;height:var(--foot-h);z-index:1000;opacity:0;visibility:hidden;transition:opacity .3s ease-out,visibility .3s;padding:0 20px 12px;color:#fff;mix-blend-mode:difference} #tvm-mag .chapters{position:relative;height:24px} #tvm-mag .chapters button{position:absolute;top:0;height:24px;padding:0 0 0 2px;font-family:var(--f-display) !important;font-weight:500 !important;font-size:11px !important;letter-spacing:.06em !important;text-transform:uppercase !important;opacity:.6;white-space:nowrap;max-width:14%;overflow:hidden;text-overflow:ellipsis;text-align:left !important} #tvm-mag .chapters button[aria-current="true"]{opacity:1;font-weight:700 !important} #tvm-mag .ticks{display:flex;justify-content:space-between;align-items:flex-end;height:14px} #tvm-mag .ticks span{width:1px;height:6px;background:currentColor;opacity:.35} #tvm-mag .ticks span.on{height:14px;opacity:1} #tvm-mag .ticks span.mark{height:14px;opacity:.7} /* ---------- Khung cuộn ngang ---------- */ #tvm-mag .hs,#tvm-mag .hs__sticky,#tvm-mag .hs__track{position:relative} #tvm-mag .panel{position:relative;overflow:hidden} #tvm-mag.is-h .hs__sticky{position:sticky;top:var(--top,0px);height:calc(100vh - var(--top,0px));height:calc(100dvh - var(--top,0px));overflow:hidden} #tvm-mag.is-h .hs__track{display:flex;height:100%;width:max-content;will-change:transform} #tvm-mag.is-h .panel{height:100%;flex:0 0 auto} #tvm-mag .fullh{min-height:100svh} #tvm-mag.is-h .fullh{min-height:0} /* ---------- Trời, mây, tia nắng, hạt ---------- */ #tvm-mag .sky{color:#fff;background: radial-gradient(70% 60% at 72% 100%,rgba(205,238,255,.95) 0,rgba(143,216,255,.6) 30%,rgba(63,164,255,0) 60%), linear-gradient(180deg,#1F6BFF 0%,#2E8CFF 45%,#6CC6FF 100%)} #tvm-mag .sky-soft{background:linear-gradient(180deg,#7ECBFF 0%,#BFE7FF 50%,#F3F8FF 100%)} #tvm-mag .rays{position:absolute;left:50%;top:50%;width:260vh;height:260vh;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none; background:repeating-conic-gradient(from 0deg,rgba(255,255,255,.22) 0 4deg,rgba(255,255,255,0) 4deg 12deg); -webkit-mask:radial-gradient(circle,#000 0,#000 18%,transparent 52%);mask:radial-gradient(circle,#000 0,#000 18%,transparent 52%)} #tvm-mag .clouds,#tvm-mag .spiral{position:absolute;inset:0;width:100%;height:100%;pointer-events:none} #tvm-mag .grain::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.2;mix-blend-mode:overlay; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")} #tvm-mag .stars{position:absolute;inset:0;pointer-events:none; background-image:radial-gradient(circle,rgba(255,255,255,.9) 0 1px,transparent 1.5px),radial-gradient(circle,rgba(255,255,255,.6) 0 1px,transparent 1.5px); background-size:120px 140px,190px 170px;background-position:10px 20px,70px 90px} #tvm-mag .ph{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block} #tvm-mag .obj{position:absolute;display:block;pointer-events:none;filter:drop-shadow(0 10px 18px rgba(13,27,76,.22))} #tvm-mag .obj svg{width:100%;height:100%;display:block} #tvm-mag .float{animation:tvm-float 7s ease-in-out infinite} #tvm-mag .float.f2{animation-duration:9s;animation-delay:-2s} #tvm-mag .float.f3{animation-duration:6s;animation-delay:-4s} @keyframes tvm-float{0%,100%{transform:translate3d(0,0,0) rotate(var(--rot,0deg))}50%{transform:translate3d(0,-14px,0) rotate(calc(var(--rot,0deg) + 6deg))}} /* Ảnh nhân vật dạng sticker */ #tvm-mag .hero-cut{position:absolute;z-index:2;bottom:0;height:92%;width:auto;max-width:none;filter:drop-shadow(0 24px 40px rgba(15,42,143,.35))} #tvm-mag .halo{position:absolute;z-index:1;border-radius:50%;background:radial-gradient(circle,#FFF6C8 0,#FFE27A 40%,rgba(255,210,63,0) 70%)} /* ---------- P1 Bìa ---------- */ #tvm-mag .cover{display:grid !important;align-content:center;padding:110px 24px 0} #tvm-mag.is-h .cover{width:100cqw;padding:0 0 0 6cqw} #tvm-mag .cover__in{position:relative;z-index:3;max-width:640px} #tvm-mag .pill{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:999px;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.5);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)} #tvm-mag .pill i{width:8px;height:8px;border-radius:50%;background:var(--sun)} #tvm-mag .cover h1{margin-top:24px;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(36px,4.2cqw,72px) !important;line-height:1 !important;letter-spacing:-.03em !important} #tvm-mag .cover h1 .nm{color:var(--sun)} #tvm-mag .cover h1 .w{display:inline-block;opacity:0;transform:translateY(36px) rotate(-2deg);transition:opacity .7s ease-out,transform .8s cubic-bezier(.2,.8,.2,1)} #tvm-mag .cover.in h1 .w{opacity:1;transform:none} #tvm-mag .cover .bigq{margin-top:26px;font-family:var(--f-poem) !important;font-style:italic !important;font-weight:300 !important;font-size:clamp(24px,2.3cqw,38px) !important;line-height:1.25 !important;max-width:22ch} #tvm-mag .cover .bigq::before{content:"“";color:var(--sun);font-weight:400 !important} #tvm-mag .cover .bigq::after{content:"”";color:var(--sun);font-weight:400 !important} #tvm-mag .cover__art{position:relative;height:62svh;margin-top:30px} #tvm-mag.is-h .cover__art{position:absolute;right:0;top:0;bottom:0;width:52%;height:auto;margin:0} #tvm-mag .cover .hero-cut{right:4%} #tvm-mag.is-h .cover .hero-cut{right:8%} #tvm-mag .cover .halo{width:640px;height:640px;right:2%;top:2%} #tvm-mag .tag{position:absolute;z-index:4;display:flex;flex-direction:column;gap:2px;padding:14px 18px;border-radius:18px;background:#fff;color:var(--ink);box-shadow:0 18px 40px -18px rgba(13,27,76,.5)} #tvm-mag .tag b{font-family:var(--f-display) !important;font-weight:800 !important;font-size:18px !important;line-height:1.2 !important} #tvm-mag .tag span{font-size:13px !important;color:var(--muted)} #tvm-mag .cover .tag{left:4%;bottom:26%} #tvm-mag .badge{position:absolute;z-index:4;left:4%;top:12%;width:150px;height:150px;border-radius:50%;background:var(--sun);color:var(--ink);display:grid;place-items:center;text-align:center !important;padding:18px;font-family:var(--f-display) !important;font-weight:700 !important;font-size:13px !important;line-height:1.25 !important;transform:rotate(10deg);box-shadow:0 14px 30px -12px rgba(13,27,76,.5)} #tvm-mag .badge::before{content:"";position:absolute;inset:8px;border-radius:50%;border:1.5px dashed rgba(13,27,76,.45)} #tvm-mag .badge strong{display:block;font-size:26px !important;line-height:1 !important;margin-bottom:4px;font-weight:800 !important} /* ---------- P2 Sapo ---------- */ #tvm-mag .sapo{background:var(--cloud);padding:96px 24px;display:grid !important;gap:28px} #tvm-mag.is-h .sapo{width:min(1240px,92cqw);padding:0 7cqw;grid-template-columns:1.15fr 1fr;gap:56px;align-content:center;align-items:center} #tvm-mag .sapo__lead{position:relative;z-index:2} #tvm-mag .sapo__lead p{font-family:var(--f-display) !important;font-weight:600 !important;font-size:clamp(21px,1.75cqw,28px) !important;line-height:1.4 !important;letter-spacing:-.01em !important;color:var(--deep)} #tvm-mag .sapo__lead p::first-letter{font-weight:800 !important;color:var(--blue);font-size:3.2em !important;float:left;line-height:.85 !important;margin:6px 10px 0 0} #tvm-mag .sapo__rest{position:relative;z-index:2;display:grid;gap:18px} #tvm-mag .sapo__rest p{font-size:17px !important;line-height:1.75 !important;color:#1E2A5A} #tvm-mag .sapo__rest p:last-child{font-family:var(--f-poem) !important;font-style:italic !important;font-size:20px !important;line-height:1.5 !important;color:var(--blue)} #tvm-mag mark{background:linear-gradient(180deg,transparent 55%,rgba(255,210,63,.75) 55%);color:inherit;padding:0 2px} /* ---------- Mở Part ---------- */ #tvm-mag .partcover{display:grid !important;align-content:center;padding:120px 24px 0} #tvm-mag.is-h .partcover{width:100cqw;padding:0 0 0 7cqw} #tvm-mag .part__in{position:relative;z-index:3;max-width:560px} #tvm-mag .part__num{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:300 !important;font-size:clamp(80px,9cqw,160px) !important;line-height:.85 !important;color:var(--sun)} #tvm-mag .part__num small{display:block;font-family:var(--f-display) !important;font-style:normal !important;font-weight:600 !important;font-size:13px !important;letter-spacing:.1em !important;text-transform:uppercase !important;color:#fff;margin-bottom:10px} #tvm-mag .partcover h2{margin-top:12px;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(44px,5.6cqw,96px) !important;line-height:.95 !important;letter-spacing:-.03em !important} #tvm-mag .partcover__art{position:relative;height:64svh;margin-top:20px} #tvm-mag.is-h .partcover__art{position:absolute;right:0;top:0;bottom:0;width:58%;height:auto;margin:0} #tvm-mag .partcover .hero-cut{right:6%;height:86%} #tvm-mag .partcover .halo{width:560px;height:560px;right:4%;top:8%} #tvm-mag .bubble{position:absolute;z-index:4;max-width:360px;padding:22px 24px;border-radius:26px 26px 26px 6px;background:#fff;color:var(--ink);box-shadow:0 24px 50px -22px rgba(13,27,76,.55)} #tvm-mag .bubble p{font-family:var(--f-display) !important;font-weight:600 !important;font-size:19px !important;line-height:1.4 !important} #tvm-mag .bubble .lbl{display:block;margin-bottom:8px;color:var(--blue)} #tvm-mag .partcover .bubble{left:2%;top:18%} #tvm-mag .bubble::after{content:"";position:absolute;right:-16px;bottom:22px;border:12px solid transparent;border-left-color:#fff;border-bottom-color:#fff;transform:rotate(-12deg)} /* ---------- P4 Nội dung Part 1 ---------- */ #tvm-mag .story{background:var(--cloud);padding:96px 24px;display:grid;gap:28px} #tvm-mag.is-h .story{width:min(1360px,96cqw);padding:0 6cqw;grid-template-columns:1fr 1fr;gap:56px;align-content:center;align-items:center} #tvm-mag .story__text{position:relative;z-index:2;display:grid;gap:18px;max-width:58ch} #tvm-mag .story__text p{font-size:17px !important;line-height:1.75 !important;color:#1E2A5A} #tvm-mag .story__text p:first-child{font-family:var(--f-display) !important;font-weight:600 !important;font-size:clamp(20px,1.6cqw,26px) !important;line-height:1.45 !important;color:var(--deep)} #tvm-mag .ways{position:relative;z-index:2;display:grid;gap:14px} #tvm-mag .way{display:grid;grid-template-columns:72px 1fr;gap:16px;align-items:center;padding:18px 20px;border-radius:var(--r);background:#fff;box-shadow:0 18px 40px -24px rgba(13,27,76,.45)} #tvm-mag .way:nth-child(2){background:var(--blue);color:#fff;transform:translateX(36px)} #tvm-mag .way .obj{position:relative;width:72px;height:72px;filter:none} #tvm-mag .way b{display:block;font-family:var(--f-display) !important;font-weight:800 !important;font-size:22px !important;line-height:1.15 !important} #tvm-mag .way span{display:block;margin-top:4px;font-size:15px !important;line-height:1.5 !important;color:var(--muted)} #tvm-mag .way:nth-child(2) span{color:#DCE8FF} #tvm-mag .ways__cap{font-size:13px !important;color:var(--muted);padding-left:4px} /* ---------- P5 Câu chuyển sang hỏi đáp ---------- */ #tvm-mag .hook{display:grid !important;place-items:center;padding:140px 24px;text-align:center !important;background:#9FCBFF} #tvm-mag.is-h .hook{width:100cqw;padding:0 10cqw} #tvm-mag .hook figure{position:relative;z-index:2;max-width:880px;display:grid;justify-items:center} #tvm-mag .hook .ava{width:96px;height:96px;border-radius:50%;border:4px solid #fff;object-fit:cover;box-shadow:0 12px 28px -10px rgba(13,27,76,.5)} #tvm-mag .hook blockquote{margin-top:24px;font-family:var(--f-poem) !important;font-style:italic !important;font-weight:400 !important;font-size:clamp(28px,3.2cqw,52px) !important;line-height:1.2 !important;text-align:center !important;color:var(--deep);text-shadow:0 0 30px rgba(255,255,255,.9),0 0 8px rgba(255,255,255,.8)} #tvm-mag .hook figcaption{margin-top:20px} #tvm-mag .hook figcaption .pill{color:var(--deep);background:rgba(255,255,255,.75);border-color:rgba(15,42,143,.2)} #tvm-mag .down{margin-top:34px;display:inline-flex;align-items:center;gap:10px;min-height:52px;padding:0 24px;border-radius:999px;background:var(--sun);color:var(--ink);font-family:var(--f-display) !important;font-weight:700 !important;font-size:15px !important;box-shadow:0 14px 30px -14px rgba(13,27,76,.55);transition:transform .2s ease-out} #tvm-mag .down:hover{transform:translateY(3px)} #tvm-mag .down svg{width:18px;height:18px} /* ---------- Hỏi đáp (cuộn dọc) ---------- */ #tvm-mag .qa{position:relative;background:var(--cloud);padding:120px 20px 120px;overflow:hidden} #tvm-mag .qa--blue{background:linear-gradient(180deg,#E6F3FF 0%,#F3F8FF 30%)} #tvm-mag .qa__head{position:relative;z-index:2;max-width:760px;margin:0 auto 64px;display:flex;align-items:center;gap:18px} #tvm-mag .qa__head .ava{width:72px;height:72px;border-radius:50%;border:3px solid #fff;object-fit:cover;box-shadow:0 10px 22px -10px rgba(13,27,76,.5)} #tvm-mag .qa__head h2{font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(28px,3cqw,42px) !important;line-height:1.05 !important;letter-spacing:-.02em !important;color:var(--deep)} #tvm-mag .qa__head p{font-size:14px !important;color:var(--muted)} #tvm-mag .qitem{position:relative;z-index:2;max-width:760px;margin:0 auto} #tvm-mag .qitem + .qitem{margin-top:96px} #tvm-mag .q{display:grid;grid-template-columns:56px 1fr;gap:18px;align-items:start} #tvm-mag .q .qn{width:56px;height:56px;border-radius:50%;background:var(--blue);color:#fff;display:grid;place-items:center;font-family:var(--f-display) !important;font-weight:800 !important;font-size:18px !important} #tvm-mag .q h3{font-family:var(--f-display) !important;font-weight:700 !important;font-size:clamp(20px,1.8cqw,25px) !important;line-height:1.35 !important;color:var(--deep)} #tvm-mag .a{margin-top:26px;padding-left:74px;display:grid;gap:18px} #tvm-mag .a p{font-size:18px !important;line-height:1.75 !important;color:#1E2A5A} #tvm-mag .a .who{display:flex;align-items:center;gap:10px;font-family:var(--f-display) !important;font-weight:700 !important;font-size:14px !important;color:var(--blue)} #tvm-mag .a .who img{width:34px;height:34px;border-radius:50%;object-fit:cover} #tvm-mag .pull{position:relative;z-index:2;max-width:900px;margin:84px auto 0;padding:36px 40px;border-radius:28px;background:var(--blue);color:#fff;overflow:hidden} #tvm-mag .pull p{position:relative;z-index:2;font-family:var(--f-poem) !important;font-style:italic !important;font-weight:300 !important;font-size:clamp(24px,2.4cqw,36px) !important;line-height:1.3 !important} #tvm-mag .pull .lbl{position:relative;z-index:2;display:block;margin-top:16px;color:var(--sun)} #tvm-mag .blurline{transition:filter .6s ease-out,opacity .6s ease-out} #tvm-mag .blurline.is-below{filter:blur(5px);opacity:.35} #tvm-mag .blurline.is-above{opacity:.55} #tvm-mag .side-obj{position:absolute;z-index:1;opacity:.95} /* ---------- Part 2: trước / sau ---------- */ #tvm-mag .p2cover{display:grid;align-content:start;padding:120px 24px;background:#BFE8F5} #tvm-mag.is-h .p2cover{width:100cqw;padding:13vh 0 0 7cqw} #tvm-mag .p2cover .ph{object-position:left top} #tvm-mag .p2card{position:relative;z-index:2;max-width:600px;padding:32px 36px;border-radius:28px;background:rgba(255,255,255,.62);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);color:var(--ink)} #tvm-mag .p2card .part__num small{color:var(--blue)} #tvm-mag .p2card .part__num{color:var(--blue)} #tvm-mag .p2card h2{margin-top:10px;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(40px,4.6cqw,80px) !important;line-height:.95 !important;letter-spacing:-.03em !important;color:var(--deep)} #tvm-mag .p2card p{margin-top:18px;font-size:18px !important;line-height:1.65 !important;color:#163061} #tvm-mag .shift{color:#fff;display:grid !important;align-content:center;gap:28px;padding:110px 24px} #tvm-mag.is-h .shift{width:min(1400px,100cqw);padding:0 7cqw} #tvm-mag .shift__head{position:relative;z-index:2;max-width:700px} #tvm-mag .shift__head h2{font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(32px,3.4cqw,54px) !important;line-height:1 !important;letter-spacing:-.02em !important} #tvm-mag .shift__head p{margin-top:12px;color:#E2EEFF;max-width:52ch} #tvm-mag .shift__grid{position:relative;z-index:2;display:grid;gap:20px} #tvm-mag.is-h .shift__grid{grid-template-columns:.8fr 1.2fr;align-items:stretch} #tvm-mag .before,#tvm-mag .after{border-radius:var(--r);padding:26px 28px} #tvm-mag .before{background:rgba(255,255,255,.16);border:1.5px dashed rgba(255,255,255,.6)} #tvm-mag .after{background:#fff;color:var(--ink);box-shadow:0 24px 50px -24px rgba(13,27,76,.55)} #tvm-mag .before .lbl,#tvm-mag .after .lbl{display:block;margin-bottom:14px} #tvm-mag .before .lbl{color:#DCE8FF} #tvm-mag .after .lbl{color:var(--blue)} #tvm-mag .before p{font-family:var(--f-display) !important;font-weight:700 !important;font-size:clamp(22px,2cqw,30px) !important;line-height:1.25 !important} #tvm-mag .after ul{display:grid;gap:12px} #tvm-mag .after li{display:grid;grid-template-columns:34px 1fr;gap:12px;align-items:start;font-family:var(--f-display) !important;font-weight:600 !important;font-size:clamp(17px,1.4cqw,21px) !important;line-height:1.35 !important} #tvm-mag .after li i{width:34px;height:34px;border-radius:50%;background:var(--sun);display:grid;place-items:center;font-style:normal !important;font-weight:800 !important;font-size:15px !important} #tvm-mag .shift__src{font-size:13px !important;color:#DCE8FF} /* ---------- Box CT-AI trong 1 phút ---------- */ #tvm-mag .box{position:relative;z-index:2;max-width:1040px;margin:110px auto 0;border-radius:32px;overflow:hidden;color:var(--ink);background:#fff;box-shadow:0 30px 70px -34px rgba(13,27,76,.5)} #tvm-mag .box__head{position:relative;padding:34px 40px;color:#fff;overflow:hidden} #tvm-mag .box__head h2{position:relative;z-index:2;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(30px,3.2cqw,48px) !important;line-height:1 !important;letter-spacing:-.02em !important} #tvm-mag .box__head h2 .poem{color:var(--sun)} #tvm-mag .box__head p{position:relative;z-index:2;margin-top:8px;color:#E2EEFF;font-size:15px !important} #tvm-mag .box__grid{display:grid;grid-template-columns:1fr;gap:0} #tvm-mag .box__cell{padding:26px 30px;border-top:1px solid var(--line)} #tvm-mag .box__cell h3{font-family:var(--f-display) !important;font-weight:700 !important;font-size:14px !important;letter-spacing:.08em !important;text-transform:uppercase !important;color:var(--blue);margin-bottom:10px} #tvm-mag .box__cell p{font-size:15px !important;line-height:1.65 !important;color:#1E2A5A} #tvm-mag .exam{display:grid;grid-template-columns:repeat(4,1fr);gap:10px} #tvm-mag .exam div{padding:12px;border-radius:16px;background:var(--cloud)} #tvm-mag .exam b{display:block;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(26px,2.6cqw,38px) !important;line-height:1 !important;color:var(--deep)} #tvm-mag .exam b small{font-size:.45em !important;font-weight:700 !important;color:var(--muted);margin-left:3px} #tvm-mag .exam span{display:block;margin-top:6px;font-size:13px !important;line-height:1.4 !important;color:var(--muted)} #tvm-mag .exam div:nth-child(3){background:var(--sun)} #tvm-mag .exam div:nth-child(3) span,#tvm-mag .exam div:nth-child(3) b small{color:var(--ink)} #tvm-mag .box__cell .exam__note{margin-top:10px;font-size:13px !important;color:var(--muted) !important} #tvm-mag .topics{counter-reset:t;display:grid;gap:8px} #tvm-mag .topics li{counter-increment:t;display:grid;grid-template-columns:30px 1fr;gap:10px;font-size:15px !important;line-height:1.5 !important} #tvm-mag .topics li::before{content:counter(t,decimal-leading-zero) !important;display:block !important;font-family:var(--f-display) !important;font-weight:800 !important;color:var(--blue)} #tvm-mag .box__foot{display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;padding:22px 30px;background:var(--cloud-2)} #tvm-mag .box__foot p{font-size:14px !important;color:var(--muted)} #tvm-mag .btn{display:inline-flex;align-items:center;gap:10px;min-height:48px;padding:0 22px;border-radius:999px;font-family:var(--f-display) !important;font-weight:700 !important;font-size:15px !important;transition:transform .2s ease-out,background-color .2s ease-out} #tvm-mag .btn:hover{transform:translateY(-2px)} #tvm-mag .btn--blue{background:var(--blue);color:#fff} #tvm-mag .btn--sun{background:var(--sun);color:var(--ink)} #tvm-mag .btn--line{border:1.5px solid #fff;color:#fff} #tvm-mag .btn svg{width:18px;height:18px} /* ---------- Lời kết ---------- */ #tvm-mag .endcard{position:relative;z-index:2;max-width:1040px;margin:110px auto 0;border-radius:32px;overflow:hidden;padding:56px 44px;color:#fff;display:grid;gap:22px} #tvm-mag.is-wide-end .endcard{grid-template-columns:1fr auto} #tvm-mag .endcard__in{position:relative;z-index:2;max-width:560px} #tvm-mag .endcard h3{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:300 !important;font-size:clamp(32px,3.4cqw,54px) !important;line-height:1.1 !important} #tvm-mag .endcard p{margin-top:16px;color:#E2EEFF;max-width:48ch} #tvm-mag .endcard .btns{margin-top:26px;display:flex;flex-wrap:wrap;gap:12px} #tvm-mag .endcard .hero-cut{right:4%;height:115%;bottom:-18%;opacity:1} #tvm-mag .credit{position:relative;z-index:2;max-width:1040px;margin:30px auto 0;font-size:13px !important;color:var(--muted)} /* ---------- Reveal ---------- */ #tvm-mag.js .reveal{opacity:0;transform:translateY(24px);filter:blur(6px);transition:opacity .8s ease-out,transform .8s cubic-bezier(.2,.8,.2,1),filter .8s ease-out} #tvm-mag.js .reveal.in{opacity:1;transform:none;filter:none} #tvm-mag .reveal.d1{transition-delay:.12s}#tvm-mag .reveal.d2{transition-delay:.24s}#tvm-mag .reveal.d3{transition-delay:.36s}#tvm-mag .reveal.d4{transition-delay:.48s} #tvm-mag.js .pop{opacity:0;transform:scale(.85) translateY(20px);transition:opacity .7s ease-out .3s,transform .8s cubic-bezier(.2,.9,.3,1.2) .3s} #tvm-mag.js .pop.in{opacity:1;transform:none} /* ---------- Mục lục ---------- */ #tvm-mag .overlay{position:fixed;inset:0;z-index:100000;background:var(--blue);color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:72px 20px 40px;overflow:auto} #tvm-mag .overlay[hidden]{display:none} #tvm-mag .overlay__close{position:absolute;top:12px;right:12px;width:44px;height:44px;display:grid;place-items:center} #tvm-mag .overlay__close svg{width:22px;height:22px} #tvm-mag .overlay h2{font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(28px,4vw,44px) !important;line-height:1.05 !important;text-align:center !important;max-width:20ch} #tvm-mag .overlay .ava{width:84px;height:84px;border-radius:50%;border:3px solid #fff;object-fit:cover;margin-bottom:18px} #tvm-mag .toc{margin-top:28px;display:grid;grid-template-columns:repeat(2,minmax(0,260px));gap:10px} #tvm-mag .toc button{min-height:52px;padding:0 18px;border-radius:16px;background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.35);text-align:left !important;font-family:var(--f-display) !important;font-weight:600 !important;font-size:15px !important} #tvm-mag .toc button b{color:var(--sun);margin-right:8px} #tvm-mag .toc button:hover{background:#fff;color:var(--ink)} /* ---------- Con trỏ ---------- */ #tvm-mag .cursor{position:fixed;left:0;top:0;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;background:#fff;mix-blend-mode:difference;pointer-events:none;z-index:100001;transition:width .2s ease-out,height .2s ease-out,margin .2s ease-out;display:none} #tvm-mag.has-cursor .cursor{display:block} #tvm-mag.has-cursor,#tvm-mag.has-cursor a,#tvm-mag.has-cursor button{cursor:none} #tvm-mag .cursor.big{width:48px;height:48px;margin:-24px 0 0 -24px} /* ---------- Responsive ---------- */ @media (min-width:760px){ #tvm-mag .box__grid{grid-template-columns:1fr 1fr} #tvm-mag .box__cell:nth-child(odd){border-right:1px solid var(--line)} } @media (max-width:1023px){ #tvm-mag .issue,#tvm-mag .all-btn .lbl2,#tvm-mag .chapters{display:none} #tvm-mag .progress{height:28px} #tvm-mag .way:nth-child(2){transform:none} #tvm-mag .badge{width:120px;height:120px;font-size:11px !important;top:4%} #tvm-mag .badge strong{font-size:20px !important} #tvm-mag .partcover .bubble{left:4%;top:4%;max-width:72%} #tvm-mag .bubble p{font-size:16px !important} #tvm-mag .halo{width:360px !important;height:360px !important} #tvm-mag .endcard .hero-cut{display:none} } @media (max-width:640px){ #tvm-mag .a{padding-left:0} #tvm-mag .q{grid-template-columns:44px 1fr;gap:12px} #tvm-mag .q .qn{width:44px;height:44px;font-size:15px !important} #tvm-mag .exam{grid-template-columns:1fr 1fr} #tvm-mag .toc{grid-template-columns:1fr} #tvm-mag .pull{padding:28px 24px} #tvm-mag .endcard{padding:40px 24px} #tvm-mag .box__head{padding:28px 24px} #tvm-mag .box__cell{padding:22px 24px} } @media (prefers-reduced-motion:reduce){ #tvm-mag .float{animation:none} #tvm-mag .reveal,#tvm-mag .pop,#tvm-mag .cover h1 .w,#tvm-mag .blurline{filter:none !important;opacity:1 !important;transform:none !important;transition:none !important} } #tvm-mag .hook figure{padding:40px 56px;background:radial-gradient(closest-side,rgba(255,255,255,.88) 0%,rgba(255,255,255,.7) 60%,rgba(255,255,255,0) 100%)} #tvm-mag.is-h .hook figure{max-width:820px} #tvm-mag .hook blockquote{font-size:clamp(26px,2.8cqw,46px) !important} /* Ảnh Canva mới */ #tvm-mag .hook{background:#BFE3FF} #tvm-mag .p2cover{background:#CBE9FF} #tvm-mag .p2cover .ph{object-position:center center} #tvm-mag.is-h .p2cover{padding:16vh 0 0 6cqw} #tvm-mag .p2card{max-width:520px} #tvm-mag .shift{background:#1F6BFF} #tvm-mag .shift .ph{object-position:right center} #tvm-mag .shift__shade{position:absolute;inset:0;background:linear-gradient(90deg,rgba(15,42,143,.72) 0%,rgba(15,42,143,.45) 45%,rgba(15,42,143,0) 70%)} #tvm-mag.is-h .shift{width:100cqw} #tvm-mag .shift__head,#tvm-mag .shift__grid,#tvm-mag .shift__src{max-width:860px} @media (max-width:1023px){ #tvm-mag .shift__shade{background:rgba(15,42,143,.6)} #tvm-mag .p2cover .ph{object-position:75% center} } /* ===== Chỉnh sửa theo góp ý ===== */ /* Thanh trên dễ đọc hơn */ #tvm-mag .topbar{mix-blend-mode:normal;color:var(--deep);align-items:center;padding:14px 20px;gap:12px} #tvm-mag .icon-btn{margin:0;width:44px;height:44px;border-radius:50%;background:#fff;color:var(--deep);box-shadow:0 8px 20px -10px rgba(13,27,76,.45)} #tvm-mag .issue{display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 18px;border-radius:999px;background:rgba(255,255,255,.92);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);box-shadow:0 8px 20px -10px rgba(13,27,76,.45);font-size:12px !important;letter-spacing:.04em !important;text-transform:none !important;line-height:1 !important} #tvm-mag .issue b{font-weight:800 !important;color:var(--deep)} #tvm-mag .issue .sep{width:6px;height:6px;border-radius:50%;background:var(--sun)} #tvm-mag .issue [data-now]{color:var(--blue);font-weight:700 !important;text-transform:uppercase !important;letter-spacing:.08em !important} /* Bìa: ảnh nhỏ hơn, sát lề phải, sticker tên gắn vào ảnh */ #tvm-mag.is-h .cover__art{width:44%} #tvm-mag .cover .hero-cut{height:82%} #tvm-mag.is-h .cover .hero-cut{right:0} #tvm-mag .cover .halo{width:520px;height:520px;right:-4%;top:6%} #tvm-mag .namesticker{position:absolute;z-index:4;right:30%;bottom:16%;display:flex;flex-direction:column;gap:2px;padding:12px 18px;border-radius:16px;background:var(--sun);color:var(--ink);border:3px solid #fff;transform:rotate(-5deg);box-shadow:0 14px 30px -14px rgba(13,27,76,.55)} #tvm-mag .namesticker b{font-family:var(--f-display) !important;font-weight:800 !important;font-size:18px !important;line-height:1.15 !important} #tvm-mag .namesticker span{font-size:13px !important;font-weight:500 !important} #tvm-mag .namesticker::after{content:"";position:absolute;right:-12px;top:50%;width:18px;height:18px;margin-top:-9px;background:var(--sun);border-right:3px solid #fff;border-top:3px solid #fff;transform:rotate(45deg);border-radius:0 4px 0 0} /* Sapo đồng nhất */ #tvm-mag .sapo__lead p,#tvm-mag .sapo__rest p,#tvm-mag .sapo__rest p:last-child{font-family:var(--f-body) !important;font-style:normal !important;font-weight:500 !important;font-size:clamp(17px,1.25cqw,20px) !important;line-height:1.75 !important;letter-spacing:0 !important;color:#1E2A5A} #tvm-mag .sapo__lead p::first-letter{font-family:var(--f-display) !important;font-weight:800 !important;color:var(--blue);font-size:3.4em !important;float:left;line-height:.82 !important;margin:6px 10px 0 0} /* Số Part to hơn, không chữ Part */ #tvm-mag .part__num{font-size:clamp(110px,12cqw,210px) !important} /* Part 2 giống Part 1 */ #tvm-mag .p2{background:#2E8CFF;color:#fff} #tvm-mag .p2 .ph{object-position:right center} #tvm-mag .p2shade{position:absolute;inset:0;background:linear-gradient(90deg,rgba(15,42,143,.6) 0%,rgba(15,42,143,.3) 38%,rgba(15,42,143,0) 60%)} #tvm-mag .p2 .part__in{text-shadow:0 2px 24px rgba(15,42,143,.35)} /* Màn sau Part 2: ảnh trái, chữ phải */ #tvm-mag .shift{background:#CDEEFF;color:var(--ink);place-items:center;padding:110px 24px} #tvm-mag .shift .ph{object-position:left center} #tvm-mag .shift__text{position:relative;z-index:2;max-width:520px;padding:32px 36px;border-radius:28px;background:rgba(255,255,255,.75);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)} #tvm-mag.is-h .shift{display:grid !important;justify-items:end;padding:0 7cqw} #tvm-mag .shift__text p{font-family:var(--f-display) !important;font-weight:600 !important;font-size:clamp(22px,2cqw,32px) !important;line-height:1.35 !important;color:var(--deep)} /* Màn chuyển: chữ rõ */ #tvm-mag .hook figure{padding:44px 52px;border-radius:32px;background:rgba(255,255,255,.86);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);box-shadow:0 30px 60px -30px rgba(13,27,76,.5)} #tvm-mag .hook blockquote{text-shadow:none;color:var(--deep)} #tvm-mag .hook figcaption{margin-top:18px;font-family:var(--f-display) !important;font-weight:700 !important;font-size:15px !important;color:var(--blue);letter-spacing:.02em !important} #tvm-mag .hook figcaption::before{content:"";display:inline-block;width:28px;height:2px;background:var(--blue);vertical-align:middle;margin-right:10px} /* Hỏi đáp: Q, cỡ chữ bằng nhau, avatar thẳng hàng Q */ #tvm-mag .qa{padding-top:110px} #tvm-mag .q .qn{font-size:24px !important} #tvm-mag .q h3{font-size:18px !important;line-height:1.75 !important;font-weight:700 !important} #tvm-mag .a{padding-left:0;display:grid;grid-template-columns:56px 1fr;gap:18px;align-items:start} #tvm-mag .aav{width:56px;height:56px;border-radius:50%;object-fit:cover;border:3px solid #fff;box-shadow:0 8px 18px -8px rgba(13,27,76,.45)} #tvm-mag .atext{display:grid;gap:18px} #tvm-mag .a .who{display:block;font-family:var(--f-display) !important;font-weight:700 !important;font-size:14px !important;color:var(--blue);line-height:1.2 !important;margin-bottom:-8px} /* Mục lục 2 ô Part */ #tvm-mag .overlay{background:var(--deep)} #tvm-mag .overlay h2{font-size:13px !important;font-weight:600 !important;letter-spacing:.1em !important;text-transform:uppercase !important;color:#BFD3FF;margin-bottom:22px} #tvm-mag .covers{display:flex;gap:14px;flex-wrap:wrap;justify-content:center} #tvm-mag .cv{width:min(300px,44vw);aspect-ratio:9/15;position:relative;overflow:hidden;border-radius:var(--r);display:flex;flex-direction:column;justify-content:flex-end;padding:20px;text-align:left !important;color:#fff;background:var(--blue);transition:transform .3s ease-out} #tvm-mag .cv:hover{transform:translateY(-6px)} #tvm-mag .cv__shade{position:absolute;inset:0;background:linear-gradient(0deg,rgba(15,42,143,.92) 0%,rgba(15,42,143,.55) 34%,rgba(15,42,143,0) 60%)} #tvm-mag .cv__num,#tvm-mag .cv__title,#tvm-mag .cv__row{position:relative;z-index:2} #tvm-mag .cv__num{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:300 !important;font-size:64px !important;line-height:.9 !important;color:var(--sun)} #tvm-mag .cv__title{margin-top:6px;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(22px,2.4vw,28px) !important;line-height:1.05 !important} #tvm-mag .cv__row{margin-top:12px;display:flex;justify-content:space-between;align-items:center;gap:8px;font-family:var(--f-display) !important;font-size:11px !important;letter-spacing:.04em !important;text-transform:uppercase !important;color:#DCE8FF} #tvm-mag .cv__tag{padding:4px 12px;border-radius:999px;background:var(--sun);color:var(--ink);font-weight:700 !important} @media (max-width:1023px){ #tvm-mag .issue b{display:none} #tvm-mag .issue .sep{display:none} #tvm-mag .namesticker{right:auto;left:4%;bottom:10%} #tvm-mag .namesticker::after{display:none} } @media (max-width:640px){ #tvm-mag .a{grid-template-columns:44px 1fr;gap:12px} #tvm-mag .aav{width:44px;height:44px} #tvm-mag .hook figure{padding:28px 22px} #tvm-mag .shift__text{padding:24px} } #tvm-mag .cover .hero-cut{height:74%} #tvm-mag .namesticker{right:34%;bottom:12%} #tvm-mag .toc[hidden]{display:none} @media (max-width:640px){#tvm-mag .covers{gap:10px;flex-wrap:nowrap}#tvm-mag .cv{width:42vw;padding:14px}#tvm-mag .cv__num{font-size:44px !important}#tvm-mag .cv__title{font-size:18px !important}#tvm-mag .cv__row{flex-direction:column;align-items:flex-start;font-size:10px !important}} @media (max-width:1023px){#tvm-mag .cover > .obj{display:none}#tvm-mag .cover .clouds{opacity:.5}} /* ===== Vòng góp ý 2 ===== */ #tvm-mag .cover{background:#1F6BFF} #tvm-mag .p1{background:#1C8FB8;color:#fff} #tvm-mag .cover .ph,#tvm-mag .p1 .ph{object-position:center center} #tvm-mag .cover__shade{position:absolute;inset:0;background:linear-gradient(90deg,rgba(15,42,143,.55) 0%,rgba(15,42,143,.25) 38%,rgba(15,42,143,0) 58%)} #tvm-mag .cover h1{font-size:clamp(36px,4cqw,68px) !important} #tvm-mag .cover .bigq{max-width:none;width:min(640px,46cqw);font-size:clamp(20px,1.8cqw,30px) !important} /* Sapo 3 cột */ #tvm-mag.is-h .sapo{width:min(1500px,100cqw);grid-template-columns:repeat(3,minmax(0,1fr));gap:44px;padding:0 7cqw;align-items:center} #tvm-mag .sapo__col{position:relative;z-index:2;font-family:var(--f-body) !important;font-weight:500 !important;font-size:clamp(17px,1.2cqw,19px) !important;line-height:1.75 !important;color:#1E2A5A;padding-top:0;border-top:0} /* Nội dung Part 1: 2 cột song song, cùng font */ #tvm-mag.is-h .story{width:min(1280px,92cqw);grid-template-columns:1fr;padding:0 7cqw} #tvm-mag .story__text{max-width:none;display:grid;gap:44px} #tvm-mag.is-h .story__text{grid-template-columns:1fr 1fr} #tvm-mag .story__text p,#tvm-mag .story__text p:first-child{font-family:var(--f-body) !important;font-weight:500 !important;font-size:clamp(17px,1.3cqw,20px) !important;line-height:1.75 !important;color:#1E2A5A} /* Màn sau Part 2: chỉ chữ */ #tvm-mag .shift__text{background:none;padding:0;-webkit-backdrop-filter:none;backdrop-filter:none;border-radius:0} #tvm-mag .shift__text p{text-shadow:0 0 24px rgba(255,255,255,.9),0 0 6px rgba(255,255,255,.8)} @media (max-width:1023px){#tvm-mag .cover .bigq{width:auto}#tvm-mag .cover__shade{background:linear-gradient(180deg,rgba(15,42,143,.6) 0%,rgba(15,42,143,.25) 55%,rgba(15,42,143,0) 100%)}} #tvm-mag .cover .halo,#tvm-mag .p1 .halo{display:none} #tvm-mag .chapters button{max-width:19%} /* ===== Vòng góp ý 3 ===== */ /* căn đều hai bên */ #tvm-mag .sapo__col,#tvm-mag .story__text p,#tvm-mag .a p,#tvm-mag .q h3{text-align:justify !important;text-justify:inter-word;hyphens:auto;-webkit-hyphens:auto} /* Bìa: ảnh vào giữa hơn, mây che mép cắt */ #tvm-mag.is-h .cover__art{width:50%;right:6cqw} #tvm-mag.is-h .cover .hero-cut{right:0} #tvm-mag .cutcloud{position:absolute;z-index:3;left:-6%;right:-6%;bottom:-3%;height:19%;pointer-events:none;filter:drop-shadow(0 -8px 22px rgba(15,42,143,.25))} #tvm-mag .cutcloud svg,#tvm-mag .cutcloud2 svg{display:block;width:100%;height:100%} #tvm-mag .cutcloud2{position:absolute;z-index:3;right:-9%;bottom:30%;width:20%;aspect-ratio:300/160;pointer-events:none;filter:drop-shadow(0 10px 18px rgba(15,42,143,.28))} #tvm-mag .cover .namesticker{z-index:5} @media (max-width:1023px){#tvm-mag .cutcloud{left:-12%;right:-12%}#tvm-mag .cutcloud2{right:-4%;width:26%}} /* Màu nổi hơn cho tiêu đề và câu trích ở bìa */ #tvm-mag .cover h1 .rest{color:#A8F0FF;text-shadow:0 2px 18px rgba(8,30,120,.45)} #tvm-mag .cover .bigq{color:#FFE27A;font-weight:400 !important;text-shadow:0 2px 16px rgba(8,30,120,.55)} #tvm-mag .cover .bigq::before,#tvm-mag .cover .bigq::after{color:#fff} #tvm-mag .cover .hero-cut{-webkit-mask-image:linear-gradient(90deg,#000 0,#000 90%,transparent 100%),linear-gradient(180deg,#000 0,#000 94%,transparent 100%);-webkit-mask-composite:source-in;mask-image:linear-gradient(90deg,#000 0,#000 90%,transparent 100%),linear-gradient(180deg,#000 0,#000 94%,transparent 100%);mask-composite:intersect} #tvm-mag .cutcloud2{right:-12%;bottom:12%;width:30%} #tvm-mag .cutcloud2{right:-10%;bottom:7%;width:24%} #tvm-mag #qa2{padding-bottom:30svh}#tvm-mag .credit{margin-top:40px} /* Sapo: 3 cột thẳng hàng theo mép trên, không so le */ #tvm-mag.is-h .sapo{align-items:start;align-content:center} /* Ảnh bìa: bỏ drop-shadow vì bị mask cắt thành vệt mờ hình vuông quanh nhân vật */ #tvm-mag .cover .hero-cut{filter:none !important} /* Thẻ tên dạng băng cá nhân (band-aid), to hơn, dán giữa cánh tay */ #tvm-mag .cover .namesticker{position:absolute !important;z-index:5;left:var(--bx,60%) !important;top:var(--by,82%) !important;right:auto !important;bottom:auto !important;translate:-50% -50%;rotate:-10deg;display:flex;flex-direction:column;align-items:center;text-align:center !important;gap:3px;padding:17px 64px;border:0;border-radius:999px;background:linear-gradient(180deg,#FBD9B5 0%,#F2BF93 55%,#EDB284 100%);color:var(--ink);box-shadow:0 14px 26px -12px rgba(13,27,76,.6),inset 0 2px 0 rgba(255,255,255,.55),inset 0 -3px 0 rgba(150,86,44,.2);white-space:nowrap} #tvm-mag .cover .namesticker::before{content:"";position:absolute;left:46px;right:46px;top:7px;bottom:7px;border-radius:10px;background:#FFF7EC;box-shadow:inset 0 0 0 1px rgba(150,86,44,.14),0 0 0 1px rgba(255,255,255,.35);z-index:0} #tvm-mag .cover .namesticker::after{content:"" !important;display:block !important;position:absolute;inset:0;right:0;top:0;width:auto;height:auto;margin:0;border:0;border-radius:inherit;transform:none;background:radial-gradient(circle,rgba(150,86,44,.38) 0 2.2px,transparent 2.8px) left 11px top 50%/11px 11px repeat-y,radial-gradient(circle,rgba(150,86,44,.38) 0 2.2px,transparent 2.8px) left 24px top 50%/11px 11px repeat-y,radial-gradient(circle,rgba(150,86,44,.38) 0 2.2px,transparent 2.8px) right 11px top 50%/11px 11px repeat-y,radial-gradient(circle,rgba(150,86,44,.38) 0 2.2px,transparent 2.8px) right 24px top 50%/11px 11px repeat-y;z-index:0;pointer-events:none} #tvm-mag .cover .namesticker b,#tvm-mag .cover .namesticker span{position:relative;z-index:1} #tvm-mag .cover .namesticker b{font-size:clamp(22px,2.1cqw,32px) !important;line-height:1.1 !important;letter-spacing:-.01em !important;color:var(--deep)} #tvm-mag .cover .namesticker span{font-size:clamp(12px,.95cqw,14px) !important;font-weight:600 !important;letter-spacing:.02em !important;color:var(--muted)} @media (max-width:640px){ #tvm-mag .cover .namesticker{padding:11px 40px;gap:1px} #tvm-mag .cover .namesticker::before{left:30px;right:30px;top:5px;bottom:5px} #tvm-mag .cover .namesticker b{font-size:16px !important} #tvm-mag .cover .namesticker span{font-size:10.5px !important} } /* Thẻ tên (name tag): thẻ trắng có dải xanh trên cùng, lỗ đeo dây, vạch vàng dưới; ghi đè kiểu băng cá nhân ở trên */ #tvm-mag .cover .namesticker{padding:34px 40px 17px;gap:3px;border-radius:16px;background:#fff;border:0;border-bottom:6px solid var(--sun);rotate:-8deg;box-shadow:0 20px 34px -14px rgba(13,27,76,.7),0 0 0 1px rgba(13,27,76,.06)} #tvm-mag .cover .namesticker::before{left:0;right:0;top:0;bottom:auto;height:18px;border-radius:16px 16px 0 0;background:linear-gradient(90deg,var(--blue),var(--blue-2));box-shadow:none} #tvm-mag .cover .namesticker::after{inset:auto;left:50%;top:5px;width:50px;height:8px;margin:0 0 0 -25px;border-radius:99px;background:#EAF3FF;box-shadow:inset 0 1px 2px rgba(13,27,76,.55)} #tvm-mag .cover .namesticker b{font-size:clamp(26px,2.5cqw,38px) !important;color:var(--deep)} #tvm-mag .cover .namesticker span{font-size:clamp(13px,1cqw,15px) !important;color:var(--muted)} @media (max-width:640px){ #tvm-mag .cover .namesticker{padding:26px 24px 11px;border-radius:12px;border-bottom-width:5px} #tvm-mag .cover .namesticker::before{height:14px;border-radius:12px 12px 0 0} #tvm-mag .cover .namesticker::after{top:3px;width:36px;height:7px;margin-left:-18px} #tvm-mag .cover .namesticker b{font-size:18px !important} #tvm-mag .cover .namesticker span{font-size:11px !important} } /* ===== Bảng so sánh CT-AI và CT-GenAI ===== */ #tvm-mag .cmp{position:relative;z-index:2;max-width:1040px;margin:96px auto 0;border-radius:32px;overflow:hidden;background:#fff;color:var(--ink);box-shadow:0 30px 70px -34px rgba(13,27,76,.5)} #tvm-mag .cmp + .qitem{margin-top:96px} #tvm-mag .cmp__head{position:relative;padding:32px 40px;color:#fff;overflow:hidden} #tvm-mag .cmp__head h2{position:relative;z-index:2;font-family:var(--f-display) !important;font-weight:800 !important;font-size:clamp(28px,3vw,44px) !important;line-height:1.05 !important;letter-spacing:-.02em !important} #tvm-mag .cmp__head h2 .poem{color:var(--sun)} #tvm-mag .cmp__head p{position:relative;z-index:2;margin-top:8px;color:#E2EEFF;font-size:15px !important} #tvm-mag .cmp__row{display:grid;grid-template-columns:168px 1fr 1fr;border-top:1px solid var(--line)} #tvm-mag .cmp__row--cols{border-top:0;background:var(--cloud)} #tvm-mag .cmp__lab{padding:22px 24px;background:var(--cloud);font-family:var(--f-display) !important;font-weight:700 !important;font-size:13px !important;line-height:1.4 !important;letter-spacing:.08em !important;text-transform:uppercase !important;color:var(--blue)} #tvm-mag .cmp__cell{padding:22px 24px;font-size:15px !important;line-height:1.65 !important;color:#1E2A5A} #tvm-mag .cmp__cell + .cmp__cell{border-left:1px solid var(--line)} #tvm-mag .cmp__row--cols .cmp__cell{padding:18px 24px;display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px} #tvm-mag .cmp__col{display:inline-flex;align-items:center;min-height:40px;padding:0 18px;border-radius:999px;font-family:var(--f-display) !important;font-weight:800 !important;font-size:20px !important;letter-spacing:-.01em !important} #tvm-mag .cmp__col--ai{background:var(--blue);color:#fff} #tvm-mag .cmp__col--gen{background:var(--sun);color:var(--ink)} #tvm-mag .cmp__pick{display:inline-flex;align-items:center;padding:4px 12px;border-radius:999px;background:var(--sky-2);color:var(--deep);font-size:12.5px !important;font-weight:700 !important;line-height:1.3 !important} #tvm-mag .cmp__cell strong{font-weight:700 !important;color:var(--deep)} #tvm-mag .cmp__stats{display:flex;flex-wrap:wrap;gap:8px} #tvm-mag .cmp__stats span{padding:8px 12px;border-radius:14px;background:var(--cloud);font-size:13px !important;line-height:1.3 !important;color:var(--muted)} #tvm-mag .cmp__stats b{display:block;font-family:var(--f-display) !important;font-weight:800 !important;font-size:24px !important;line-height:1.1 !important;color:var(--deep)} #tvm-mag .cmp__stats span:nth-child(3){background:var(--sun);color:var(--ink)} #tvm-mag .cmp__note{margin-top:10px;font-size:13px !important;line-height:1.5 !important;color:var(--muted)} #tvm-mag .cmp__list{counter-reset:t;display:grid;gap:6px} #tvm-mag .cmp__list li{counter-increment:t;display:grid;grid-template-columns:28px 1fr;gap:8px;font-size:14.5px !important;line-height:1.5 !important} #tvm-mag .cmp__list li::before{content:counter(t,decimal-leading-zero) !important;display:block !important;font-family:var(--f-display) !important;font-weight:800 !important;color:var(--blue)} @media (max-width:760px){ #tvm-mag .cmp{border-radius:24px} #tvm-mag .cmp__head{padding:26px 22px} #tvm-mag .cmp__row{grid-template-columns:1fr} #tvm-mag .cmp__row--cols{display:none} #tvm-mag .cmp__lab{padding:14px 22px} #tvm-mag .cmp__cell{padding:18px 22px} #tvm-mag .cmp__cell + .cmp__cell{border-left:0;border-top:1px dashed var(--line)} #tvm-mag .cmp__stats{display:grid;grid-template-columns:repeat(4,1fr);gap:6px} #tvm-mag .cmp__stats span{padding:8px 4px;text-align:center !important;font-size:12px !important} #tvm-mag .cmp__stats b{font-size:21px !important} #tvm-mag .cmp__cell::before{content:attr(data-tag);display:block;width:fit-content;margin-bottom:8px;padding:3px 12px;border-radius:999px;font-family:var(--f-display) !important;font-weight:800 !important;font-size:13px !important} #tvm-mag .cmp__cell--ai::before{background:var(--blue);color:#fff} #tvm-mag .cmp__cell--gen::before{background:var(--sun);color:var(--ink)} } #tvm-mag .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap} /* ===== Màn hình cảm ơn cuối bài ===== */ #tvm-mag .endscr{position:relative;overflow:hidden;min-height:100svh;display:grid !important;align-items:center;background:#1F6BFF;padding:120px 24px 0;isolation:isolate} #tvm-mag .endscr__bg{position:absolute;inset:0;width:100%;height:100%;max-width:none;object-fit:cover;object-position:center;z-index:0} #tvm-mag .endscr__shade{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(15,42,143,.62) 0%,rgba(15,42,143,.3) 58%,rgba(15,42,143,0) 100%)} #tvm-mag .endscr__in{position:relative;z-index:3;display:grid;gap:22px;max-width:640px;padding-bottom:40px} #tvm-mag .endscr__in p{font-family:var(--f-body) !important;font-weight:500 !important;font-size:clamp(18px,1.55cqw,26px) !important;line-height:1.6 !important;color:#fff;text-shadow:0 2px 14px rgba(8,30,120,.55)} #tvm-mag .endscr__in .nm{font-family:var(--f-display) !important;font-weight:800 !important;color:var(--sun)} #tvm-mag .endscr__in .endscr__hope{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:400 !important;font-size:clamp(18px,1.5cqw,25px) !important;line-height:1.5 !important;color:#FFE27A} #tvm-mag .endscr__art{position:relative;z-index:2;height:52svh;margin:0 auto} #tvm-mag .endscr__art img{display:block;height:100%;width:auto;max-width:none;margin:0 auto;-webkit-mask-image:linear-gradient(90deg,#000 0,#000 80%,transparent 99%),linear-gradient(180deg,#000 0,#000 88%,transparent 100%);-webkit-mask-composite:source-in;mask-image:linear-gradient(90deg,#000 0,#000 80%,transparent 99%),linear-gradient(180deg,#000 0,#000 88%,transparent 100%);mask-composite:intersect} @media (min-width:1024px){ #tvm-mag .endscr{padding:0 0 0 6cqw} #tvm-mag .endscr__shade{background:linear-gradient(90deg,rgba(15,42,143,.6) 0%,rgba(15,42,143,.3) 40%,rgba(15,42,143,0) 62%)} #tvm-mag .endscr__in{width:min(640px,46cqw);padding-bottom:0} #tvm-mag .endscr__art{position:absolute;right:-3cqw;bottom:0;height:68%;margin:0} } #tvm-mag .endscr{padding:96px 24px;justify-items:center;align-items:center} #tvm-mag .endscr__in{width:min(700px,100%);max-width:700px;margin:0 auto;padding-bottom:0;text-align:center !important} #tvm-mag .endscr__in p{text-align:center !important;text-shadow:0 1px 12px rgba(10,50,170,.7),0 0 3px rgba(10,50,170,.45)} #tvm-mag .endscr__in .endscr__hope{color:#FFEFA8} #tvm-mag .endscr__in::before{content:"";position:absolute;inset:-70px -110px;z-index:-1;pointer-events:none;background:radial-gradient(closest-side,rgba(16,62,214,.62) 0%,rgba(16,62,214,.4) 55%,rgba(16,62,214,0) 100%)} @media (min-width:1024px){#tvm-mag .endscr{padding:96px 6cqw}} #tvm-mag.is-h .endscr{display:grid !important;width:100vw;padding:0} #tvm-mag .thx{position:relative;z-index:2;max-width:1040px;margin:96px auto 0;border-radius:28px;overflow:hidden;isolation:isolate;min-height:420px;display:grid !important;align-items:center;justify-items:start;padding:64px 56px;box-shadow:0 30px 60px -30px rgba(15,42,143,.35)} #tvm-mag .thx__bg{position:absolute;inset:0;width:100%;height:100%;max-width:none;object-fit:cover;object-position:center;z-index:-2} #tvm-mag .thx::before{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(90deg,rgba(8,28,120,.82) 0%,rgba(10,36,150,.62) 42%,rgba(12,44,170,.2) 62%,rgba(12,44,170,0) 75%)} #tvm-mag .thx__in{max-width:540px;display:grid;gap:18px;text-align:left !important} #tvm-mag .thx__in p{color:#fff;font-family:var(--f-body) !important;font-weight:600 !important;font-size:clamp(17px,1.4cqw,22px) !important;line-height:1.6 !important;text-shadow:0 2px 6px rgba(5,20,90,.55)} #tvm-mag .thx__in .nm{font-family:var(--f-display) !important;font-weight:800 !important;color:var(--sun)} #tvm-mag .thx__in .thx__hope{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:500 !important;color:#FFE58A} @media (max-width:640px){#tvm-mag .thx{padding:44px 22px;min-height:360px;border-radius:20px}#tvm-mag .thx__bg{object-position:20% center}#tvm-mag .thx::before{background:linear-gradient(180deg,rgba(8,28,120,.78),rgba(10,36,150,.6))}} /* Name tag kéo ngang, dựng thẳng, không nghiêng */ #tvm-mag .cover .namesticker{rotate:0deg;width:auto;padding:34px 44px 17px;white-space:nowrap} #tvm-mag .cover .namesticker b{font-size:clamp(26px,2.5cqw,38px) !important} #tvm-mag .cover .namesticker span{font-size:clamp(13px,1cqw,15px) !important} @media (max-width:640px){ #tvm-mag .cover .namesticker{padding:26px 24px 11px} #tvm-mag .cover .namesticker b{font-size:18px !important} #tvm-mag .cover .namesticker span{font-size:11px !important} } /* Vòng 4: bỏ mây phủ trước nhân vật, mép ảnh tan vào nền; font đoạn Part 2 giống câu dẫn */ #tvm-mag .cutcloud,#tvm-mag .cutcloud2{display:none} #tvm-mag .cover .hero-cut{-webkit-mask-image:linear-gradient(90deg,#000 0,#000 80%,transparent 99%),linear-gradient(180deg,#000 0,#000 88%,transparent 100%);mask-image:linear-gradient(90deg,#000 0,#000 80%,transparent 99%),linear-gradient(180deg,#000 0,#000 88%,transparent 100%)} #tvm-mag .shift__text p{font-family:var(--f-poem) !important;font-style:italic !important;font-weight:400 !important;font-size:clamp(24px,2.4cqw,40px) !important;line-height:1.3 !important;color:var(--deep)} AI TrangVM & ISTQB® CT-AIMở đầu TrangVMvà ISTQB® Certified Tester AI Testing Thay đổi lớn nhất là cách mình đặt câu hỏi khi tiếp cận một tính năng Vũ Minh Trang (Max)Manual Tester · Kaopiz Global AI đã và đang thay đổi cách chúng ta làm việc tại Kaopiz, từ cách xử lý công việc hằng ngày đến cách phát triển sản phẩm. Với Tester, sự thay đổi này cũng diễn ra theo hai hướng: AI trở thành công cụ hỗ trợ các hoạt động kiểm thử, đồng thời xuất hiện ngày càng nhiều trong chính những sản phẩm cần được kiểm thử. Điều đó cũng mở ra những yêu cầu mới về kiến thức và cách tiếp cận công việc của Tester. Từ những thay đổi đó, mỗi Tester có thể bắt đầu nâng cấp kỹ năng theo một cách riêng. Với Vũ Minh Trang (Max), Manual Tester thuộc Kaopiz Global, hành trình ấy gắn liền với ISTQB® Certified Tester AI Testing (CT-AI) v2 – chứng chỉ quốc tế về kiểm thử các hệ thống ứng dụng AI. Trang cũng là người đầu tiên tại Kaopiz đạt được chứng chỉ này, đánh dấu một cột mốc đáng nhớ trong hành trình học hỏi và phát triển chuyên môn. Điều gì đã thôi thúc TrangVM theo đuổi CT-AI, và hành trình học tập ấy mang đến những kinh nghiệm gì mà các anh chị em Kaopizer có thể tham khảo? Cùng khám phá câu chuyện của Trang, đồng thời gửi lời chúc mừng cho dấu mốc đặc biệt này nhé! 01 Trước thách thức AI Với hơn 4 năm làm kiểm thử phần mềm, Minh Trang đã quen với những quy trình và cách tiếp cận trong công việc. Tuy nhiên trong 1 năm trở lại đây, khi bắt đầu tiếp xúc nhiều hơn với AI, Trang nhận ra không phải những kinh nghiệm kiểm thử trước đây đều có thể áp dụng nguyên vẹn. AI xuất hiện trong công việc kiểm thử theo hai cách: vừa hỗ trợ Tester gợi ý test case, sinh dữ liệu kiểm thử hay viết bug report rõ ràng hơn, vừa trở thành đối tượng cần kiểm thử khi được tích hợp vào các sản phẩm. Từ đó mà những băn khoăn mới cũng xuất hiện, cùng với đó là sự bắt đầu trong hành trình tìm hiểu về kiểm thử AI “Mình có thử tự tìm hiểu trên mạng, nhưng kiến thức khá rời rạc, nên mình nghĩ cần một lộ trình học bài bản hơn, và CT-AI là…” Vũ Minh Trang (Max) QĐiều gì đã thôi thúc bạn lựa chọn theo đuổi chứng chỉ ISTQB® Certified Tester – AI Testing (CT‑AI) vào thời điểm đó? Có tình huống thực tế, dự án hay trải nghiệm nào khiến Trang nhận ra mình cần tìm hiểu sâu hơn về kiểm thử AI bài bản hơn không? TrangVM Trước giờ mình quen với việc nhập cùng một dữ liệu thì phải ra cùng một kết quả, đúng là đúng, sai là sai. Nhưng với AI thì khác: hỏi cùng một câu mà mỗi lần nó trả lời một kiểu, mà kiểu nào nghe cũng có vẻ hợp lý. Lúc đó mình thật sự bối rối, không biết nên viết test case thế nào, cũng không chắc khi nào thì nên log bug. Mình có thử tự tìm hiểu trên mạng, nhưng kiến thức khá rời rạc, nên mình nghĩ cần một lộ trình học bài bản hơn, và CT-AI là lựa chọn phù hợp. Thật ra, mình cũng từng cân nhắc giữa CT-AI và CT-GenAI. CT-GenAI tập trung vào việc dùng AI tạo sinh, như ChatGPT, để hỗ trợ công việc test: viết prompt sao cho hiệu quả, nhờ AI sinh test case hay dữ liệu test, và biết những rủi ro khi dùng AI. Còn CT-AI tập trung vào việc kiểm thử chính những hệ thống có AI bên trong: AI học từ dữ liệu như thế nào, tại sao nó khó test, và dùng kỹ thuật gì để đánh giá nó. Mình muốn hiểu rõ hơn cách AI hoạt động, vì sao kiểm thử AI khác với phần mềm thông thường và làm thế nào để đánh giá chất lượng của những hệ thống này. Đó cũng là lý do mình quyết định chọn CT-AI trước. CT-AI và CT-GenAI So sánh nhanh hai chứng chỉ ISTQB® về AI Tiêu chí CT-AILựa chọn của Trang CT-GenAI Trọng tâm Kiểm thử chính những hệ thống có AI bên trong. Dùng AI tạo sinh, như ChatGPT, để hỗ trợ công việc test. Học được gì Kiểm thử hệ thống AI, chủ yếu là machine learning, có đề cập thêm GenAI. Áp dụng GenAI, LLM và công cụ AI vào toàn bộ quy trình kiểm thử. Theo trang chính thức của ISTQB®: CT-AI syllabus v2.0, CT-GenAI syllabus v1.1 Trang CT-AI Trang CT-GenAI QVừa đảm bảo công việc hằng ngày, vừa chuẩn bị cho một chứng chỉ mới không phải lúc nào cũng dễ dàng. Bạn đã tổ chức việc học như thế nào? TrangVM Mình đã ôn tập trong khoảng hơn một tháng. Vì vẫn phải đảm bảo công việc ở dự án nên mình chọn cách học đều đặn thay vì dồn ép. Phần học lý thuyết chính mình để vào cuối tuần, trong tuần, mình cố gắng dành ra ít nhất ba buổi tối để làm thêm các bộ câu hỏi, mục đích là ôn lại và ghi nhớ những gì đã học vào cuối tuần trước đó. Cách này giúp kiến thức được “nhắc lại” liên tục nên mình nhớ lâu hơn, đồng thời qua các bộ câu hỏi mình cũng phát hiện ra phần nào mình còn hiểu chưa chắc để quay lại học kỹ. QVậy đâu là thử thách lớn nhất khi ôn luyện chứng chỉ ISTQB® CT-AI? TrangVM Khó khăn lớn nhất với mình là một số chương có lượng kiến thức nhiều hơn hẳn những chương khác, đồng thời chứa rất nhiều thuật ngữ và định nghĩa mới mà trước đây mình chưa từng gặp. Đặc biệt là Chương 3 – Machine Learning, tìm hiểu về cách xây dựng và đánh giá mô hình học máy, và Chương 6 – Model Testing for ML Systems, tập trung vào các kỹ thuật kiểm thử chính những mô hình này. Mình đã chọn cách chia nhỏ nội dung của những chương này và học trong nhiều buổi, mỗi buổi chỉ tập trung vào một nhóm khái niệm. Bên cạnh đó, mình làm mindmap cho từng chương để nhìn thấy mối liên hệ giữa các khái niệm, thay vì chỉ học thuộc từng định nghĩa riêng lẻ. Đến giờ, những mindmap này vẫn là tài liệu tra cứu rất tiện mỗi khi mình cần xem lại một khái niệm trong công việc. 02 Bước tiến của Tester Chứng chỉ không phải là đích đến của cuộc hành trình. Điều giá trị hơn cả là những góc nhìn mới đã giúp TrangVM tiếp cận việc kiểm thử AI bài bản và sâu sắc hơn. QSau khi hoàn thành ISTQB® CT-AI, kiến thức mới đã mang lại cho Trang những thay đổi gì trong cách nhìn nhận công việc kiểm thử? TrangVM Thay đổi lớn nhất với mình là cách nhìn nhận và đặt câu hỏi khi tiếp cận một tính năng. Trước đây, mình chủ yếu quan tâm đến việc “chức năng này chạy đúng hay sai?”. Còn bây giờ, với các tính năng AI, mình quan tâm thêm đến việc kết quả có ổn định và nhất quán không, mô hình có bị thiên lệch với một nhóm dữ liệu nào không, hay nó phản ứng thế nào với dữ liệu bất thường. Để có được những góc nhìn đó, quá trình ôn thi giúp mình hiểu hơn về cách mô hình Machine Learning được huấn luyện, đánh giá và những rủi ro có thể xuất hiện trong quá trình đó. Mình cũng được tìm hiểu các kỹ thuật kiểm thử chuyên biệt, chẳng hạn như Metamorphic Testing – kiểm tra xem kết quả có thay đổi phù hợp khi đầu vào được biến đổi theo một quy luật nhất định hay không. Mình cũng biết cách đánh giá hiệu quả của AI thay vì chỉ dựa vào cảm tính, đồng thời chú ý hơn đến chất lượng dữ liệu đầu vào và nguy cơ AI đối xử thiếu công bằng với một nhóm người dùng nào đó. QBạn đã vận dụng những điều đã học vào dự án thực tế như thế nào? TrangVM So với trước đây, mình đã có thể chủ động hơn trong việc trao đổi với team ngay từ giai đoạn phân tích yêu cầu, thay vì đợi đến lúc test mới thấy vướng. Ví dụ khi dùng công cụ AI để gợi ý test case, mình sẽ review thật kỹ đầu ra, vì mình hiểu rõ hơn những hạn chế của AI như việc nó có thể “bịa” thông tin hoặc bỏ sót các trường hợp biên. QTheo Trang, ISTQB® CT-AI có thể là lựa chọn phù hợp với những ai đang muốn phát triển năng lực trong lĩnh vực kiểm thử AI? Nếu muốn bắt đầu ngay hôm nay, các Kaopizer nên chuẩn bị những gì và bắt đầu từ đâu? TrangVM Theo mình, bất kỳ ai đang quan tâm tới AI đều có thể tìm hiểu chứng chỉ này, và đặc biệt phù hợp với những bạn đang hoặc sắp tham gia kiểm thử các sản phẩm có tích hợp AI. Bất cứ ai làm việc với tính năng AI cũng sẽ thấy kiến thức này rất hữu ích, vì nó giúp cả team hiểu rủi ro chất lượng của hệ thống AI theo cùng một cách. Với những bạn mới bắt đầu, mình khuyên nên tải syllabus CT-AI chính thức trên trang ISTQB và đọc lướt mục lục cùng mục tiêu học tập của từng chương để hình dung tổng quan về nội dung và khối lượng kiến thức cần học. Trong quá trình học, các bạn có thể làm mindmap để hệ thống lại kiến thức, đồng thời nhờ AI tạo các bộ câu hỏi để tự ôn tập và ghi nhớ những nội dung vừa học. CT-AI trong 1 phút ISTQB® Certified Tester AI Testing, phiên bản 2.0 Đối tượng phù hợpChứng chỉ hướng đến những cá nhân tham gia vào hoạt động kiểm thử các hệ thống ứng dụng AI. Chứng chỉ cũng phù hợp với những cá nhân mong muốn có kiến thức tổng quan về kiểm thử các hệ thống ứng dụng AI. Điều kiện dự thiChứng chỉ ISTQB® Certified Tester Foundation Level (CTFL) là điều kiện tiên quyết để đạt được chứng chỉ CT-AI v2.0. Cấu trúc đề thi 40câuSố câu hỏi 44điểmTổng điểm 29điểmĐiểm đạt 60phútThời gian làm bài Được cộng thêm 25% thời gian nếu thi bằng ngôn ngữ không phải tiếng mẹ đẻ. Các nội dung chính Giới thiệu về AI. Đặc tính chất lượng của hệ thống AI và tiêu chí chấp nhận. Machine Learning: dữ liệu, chỉ số hiệu năng cho bài toán phân loại và mạng nơ-ron. Kiểm thử hệ thống AI, bao gồm kiểm thử AI tạo sinh, LLM và các mức kiểm thử với hệ thống Machine Learning. Kiểm thử dữ liệu đầu vào. Kiểm thử mô hình. Kiểm thử trong phát triển Machine Learning. Tìm hiểu thêm trên trang chính thức của ISTQB® Trang chứng chỉ CT-AI QTrang muốn có thêm lời nhắn gửi gì tới độc giả không? TrangVM Ờm, Kaopiz cũng đang có chính sách hỗ trợ lệ phí thi và thưởng hấp dẫn, mình nghĩ đó cũng là động lực để các bạn có thể thi lấy chứng chỉ này đó. Chúc các Kaopizer khác may mắn nha! Cảm ơn TrangVM đã dành thời gian chia sẻ hành trình chinh phục chứng chỉ CT-AI cùng những kiến thức và kinh nghiệm hữu ích với các Kaopizer. Hy vọng câu chuyện của Trang sẽ mang đến cho các Kaopizer những góc nhìn mới về kiểm thử AI và gợi mở thêm những hướng học tập phù hợp với công việc của mỗi người. Chọn phần muốn đọc 01 Trước thách thức AI Part 1 · Hành trình đến với CT-AIĐọc 02 Bước tiến của Tester Part 2 · Sau chứng chỉĐọc (function(s){var b=atob(s),u=new Uint8Array(b.length);for(var i=0;i!==b.length;i++){u[i]=b.charCodeAt(i)}(new Function(new TextDecoder().decode(u)))()})("CihmdW5jdGlvbigpewogIHZhciByb290PWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0dm0tbWFnJyk7CiAgaWYoIXJvb3QpIHJldHVybjsKICB0cnl7IGluaXQoKTsgfWNhdGNoKGVycil7CiAgICByb290LmNsYXNzTGlzdC5yZW1vdmUoJ2pzJywnaXMtaCcpOwogICAgaWYod2luZG93LmNvbnNvbGUpY29uc29sZS53YXJuKCdbdHZtLW1hZ10gdOG6r3QgaGnhu4d1IOG7qW5nIGRvIGzhu5dpOicsZXJyKTsKICB9CiAgZnVuY3Rpb24gaW5pdCgpewogIHJvb3QuY2xhc3NMaXN0LmFkZCgnanMnKTsKICB2YXIgJD1mdW5jdGlvbihzLGMpe3JldHVybiAoY3x8cm9vdCkucXVlcnlTZWxlY3RvcihzKX07CiAgdmFyICQkPWZ1bmN0aW9uKHMsYyl7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKChjfHxyb290KS5xdWVyeVNlbGVjdG9yQWxsKHMpKX07CiAgdmFyIHJlZHVjZT1tYXRjaE1lZGlhKCcocHJlZmVycy1yZWR1Y2VkLW1vdGlvbjogcmVkdWNlKScpLm1hdGNoZXM7CiAgdmFyIG1xSD1tYXRjaE1lZGlhKCcobWluLXdpZHRoOjEwMjRweCkgYW5kIChtaW4taGVpZ2h0OjU2MHB4KScpOwogIHZhciBhYnNUb3A9ZnVuY3Rpb24oZSl7cmV0dXJuIGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wK3dpbmRvdy5wYWdlWU9mZnNldH07CgogIC8qIFTDoWNoIGNo4buvIHRpw6p1IMSR4buBICovCiAgJCQoJ1tkYXRhLXNwbGl0XScpLmZvckVhY2goZnVuY3Rpb24oaCl7CiAgICB2YXIgaT0wOwogICAgKGZ1bmN0aW9uIHdhbGsobm9kZSl7CiAgICAgIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG5vZGUuY2hpbGROb2RlcykuZm9yRWFjaChmdW5jdGlvbihuKXsKICAgICAgICBpZihuLm5vZGVUeXBlPT09Myl7CiAgICAgICAgICB2YXIgZnJhZz1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICAgICAgICBuLnRleHRDb250ZW50LnNwbGl0KC8oXHMrKS8pLmZvckVhY2goZnVuY3Rpb24odCl7CiAgICAgICAgICAgIGlmKCF0KXJldHVybjsKICAgICAgICAgICAgaWYoL15ccyskLy50ZXN0KHQpKXtmcmFnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHQpKTtyZXR1cm59CiAgICAgICAgICAgIHZhciBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtzLmNsYXNzTmFtZT0ndyc7cy50ZXh0Q29udGVudD10O3Muc3R5bGUudHJhbnNpdGlvbkRlbGF5PSgwLjIraSsrKjAuMDYpKydzJztmcmFnLmFwcGVuZENoaWxkKHMpOwogICAgICAgICAgfSk7CiAgICAgICAgICBuLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGZyYWcsbik7CiAgICAgICAgfWVsc2Ugd2FsayhuKTsKICAgICAgfSk7CiAgICB9KShoKTsKICB9KTsKCiAgLyogQ8OhYyDEkW/huqFuIGN14buZbiBuZ2FuZyAqLwogIHZhciBoc3M9JCQoJy5ocycpLm1hcChmdW5jdGlvbihlbCl7cmV0dXJuIHtlbDplbCx0cmFjazplbC5xdWVyeVNlbGVjdG9yKCcuaHNfX3RyYWNrJyksbWF4OjAsdG9wOjB9fSk7CiAgdmFyIGNoYXB0ZXJzPVtdLHRvcE9mZj0wLHdpZGU9dHJ1ZSxzdGlja3lPSz10cnVlOwoKICBmdW5jdGlvbiBmaXhlZEFuY2VzdG9yKGUpewogICAgd2hpbGUoZSYmZSE9PWRvY3VtZW50LmJvZHkmJmUhPT1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpewogICAgICB2YXIgcD1nZXRDb21wdXRlZFN0eWxlKGUpLnBvc2l0aW9uOwogICAgICBpZihwPT09J2ZpeGVkJ3x8cD09PSdzdGlja3knKXJldHVybiBlOwogICAgICBlPWUucGFyZW50RWxlbWVudDsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0KICBmdW5jdGlvbiBoZWFkZXJPZmZzZXQoKXsKICAgIHZhciBhYj1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnd3BhZG1pbmJhcicpOwogICAgaWYoYWImJmdldENvbXB1dGVkU3R5bGUoYWIpLnBvc2l0aW9uPT09J2ZpeGVkJyYmYWIub2Zmc2V0SGVpZ2h0KXJldHVybiBhYi5vZmZzZXRIZWlnaHQ7CiAgICByZXR1cm4gMDsKICB9CiAgdmFyIGhpZGRlbj1bXTsKICBmdW5jdGlvbiBoaWRlVGhlbWVCYXJzKCl7CiAgICBpZighZG9jdW1lbnQuZWxlbWVudHNGcm9tUG9pbnQpcmV0dXJuOwogICAgdmFyIHg9TWF0aC5yb3VuZCh3aW5kb3cuaW5uZXJXaWR0aC8yKTsKICAgIFt0b3BPZmYrNCx0b3BPZmYrMzAsdG9wT2ZmKzYwXS5mb3JFYWNoKGZ1bmN0aW9uKHl5KXsKICAgICAgZG9jdW1lbnQuZWxlbWVudHNGcm9tUG9pbnQoeCx5eSkuZm9yRWFjaChmdW5jdGlvbihlbCl7CiAgICAgICAgaWYocm9vdC5jb250YWlucyhlbCkpcmV0dXJuOwogICAgICAgIHZhciBmPWZpeGVkQW5jZXN0b3IoZWwpOwogICAgICAgIGlmKCFmfHxmLmlkPT09J3dwYWRtaW5iYXInfHxoaWRkZW4uaW5kZXhPZihmKT4tMSlyZXR1cm47CiAgICAgICAgaWYoZi5vZmZzZXRIZWlnaHQ+d2luZG93LmlubmVySGVpZ2h0Ki41KXJldHVybjsKICAgICAgICBoaWRkZW4ucHVzaChmKTtmLmRhdGFzZXQudHZtVmlzPWYuc3R5bGUudmlzaWJpbGl0eXx8Jyc7Zi5zdHlsZS52aXNpYmlsaXR5PSdoaWRkZW4nOwogICAgICB9KTsKICAgIH0pOwogIH0KICBmdW5jdGlvbiBzaG93VGhlbWVCYXJzKCl7aGlkZGVuLmZvckVhY2goZnVuY3Rpb24oZil7Zi5zdHlsZS52aXNpYmlsaXR5PWYuZGF0YXNldC50dm1WaXN8fCcnfSk7aGlkZGVuPVtdfQogIHZhciBpbW1lcnNpdmU9ZmFsc2U7CiAgZnVuY3Rpb24gc2V0SW1tZXJzaXZlKG9uKXsKICAgIGlmKG9uPT09aW1tZXJzaXZlKXtpZihvbiloaWRlVGhlbWVCYXJzKCk7cmV0dXJufQogICAgaW1tZXJzaXZlPW9uOwogICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoJ3R2bS1pbW1lcnNpdmUnLG9uKTsKICAgIGlmKG9uKWhpZGVUaGVtZUJhcnMoKTtlbHNlIHNob3dUaGVtZUJhcnMoKTsKICB9CiAgZnVuY3Rpb24gcHJlcGFyZUFuY2VzdG9ycygpewogICAgdmFyIG9rPXRydWU7CiAgICBmb3IodmFyIGU9cm9vdC5wYXJlbnRFbGVtZW50O2UmJmUhPT1kb2N1bWVudC5ib2R5JiZlIT09ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O2U9ZS5wYXJlbnRFbGVtZW50KXsKICAgICAgdmFyIGNzPWdldENvbXB1dGVkU3R5bGUoZSk7CiAgICAgIGlmKGNzLm92ZXJmbG93WD09PSdoaWRkZW4nfHxjcy5vdmVyZmxvd1k9PT0naGlkZGVuJyl7ZS5zdHlsZS5vdmVyZmxvdz0ndmlzaWJsZSd9CiAgICAgIGVsc2UgaWYoLyhhdXRvfHNjcm9sbCkvLnRlc3QoY3Mub3ZlcmZsb3dYK2NzLm92ZXJmbG93WSkpe29rPWZhbHNlfQogICAgICBpZihjcy50cmFuc2Zvcm0hPT0nbm9uZSd8fGNzLmZpbHRlciE9PSdub25lJ3x8Y3MucGVyc3BlY3RpdmUhPT0nbm9uZScpe29rPWZhbHNlfQogICAgfQogICAgcmV0dXJuIG9rOwogIH0KICBmdW5jdGlvbiBicmVha291dCgpewogICAgdmFyIHJvdz1yb290LmNsb3Nlc3QoJy5yb3cnKTsKICAgIGlmKHJvdyl7CiAgICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwocm93LmNoaWxkcmVuLGZ1bmN0aW9uKGMpewogICAgICAgIGlmKGMuY29udGFpbnMocm9vdCkpe2Muc3R5bGUud2lkdGg9JzEwMCUnO2Muc3R5bGUubWF4V2lkdGg9JzEwMCUnO2Muc3R5bGUuZmxleD0nMCAwIDEwMCUnfQogICAgICAgIGVsc2UgaWYoL3NpZGViYXIvaS50ZXN0KGMuY2xhc3NOYW1lKSl7Yy5zdHlsZS5kaXNwbGF5PSdub25lJ30KICAgICAgfSk7CiAgICB9CiAgICBbJ21hcmdpbi1sZWZ0Jywnd2lkdGgnXS5mb3JFYWNoKGZ1bmN0aW9uKGspe3Jvb3Quc3R5bGUucmVtb3ZlUHJvcGVydHkoayl9KTsKICAgIHJvb3Quc3R5bGUuc2V0UHJvcGVydHkoJ21heC13aWR0aCcsJ25vbmUnLCdpbXBvcnRhbnQnKTtyb290LnN0eWxlLnNldFByb3BlcnR5KCdtYXJnaW4tcmlnaHQnLCcwJywnaW1wb3J0YW50Jyk7CiAgICB2YXIgY3c9ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoOwogICAgdmFyIHB3PXJvb3QucGFyZW50RWxlbWVudD9yb290LnBhcmVudEVsZW1lbnQuY2xpZW50V2lkdGg6Y3c7CiAgICB3aWRlPXRydWU7CiAgICBpZihwdz49Y3cpcmV0dXJuOwogICAgdHJ5e2RvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5vdmVyZmxvd1g9J2NsaXAnO2RvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3dYPSdjbGlwJ31jYXRjaChfKXt9CiAgICB2YXIgbGVmdD1yb290LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7CiAgICByb290LnN0eWxlLnNldFByb3BlcnR5KCd3aWR0aCcsY3crJ3B4JywnaW1wb3J0YW50Jyk7CiAgICByb290LnN0eWxlLnNldFByb3BlcnR5KCdtYXJnaW4tbGVmdCcsKC1sZWZ0KSsncHgnLCdpbXBvcnRhbnQnKTsKICB9CgogIGZ1bmN0aW9uIGxheW91dCgpewogICAgYnJlYWtvdXQoKTsKICAgIHRvcE9mZj1oZWFkZXJPZmZzZXQoKTsKICAgIHJvb3Quc3R5bGUuc2V0UHJvcGVydHkoJy0tdG9wJyx0b3BPZmYrJ3B4Jyk7CiAgICB2YXIgaG9yaXo9bXFILm1hdGNoZXMmJndpZGUmJnN0aWNreU9LOwogICAgcm9vdC5jbGFzc0xpc3QudG9nZ2xlKCdpcy1oJyxob3Jpeik7CiAgICBoc3MuZm9yRWFjaChmdW5jdGlvbihoKXsKICAgICAgaC50cmFjay5zdHlsZS50cmFuc2Zvcm09Jyc7CiAgICAgIGlmKGhvcml6KXsKICAgICAgICBoLm1heD1NYXRoLm1heCgwLGgudHJhY2suc2Nyb2xsV2lkdGgtcm9vdC5jbGllbnRXaWR0aCk7CiAgICAgICAgaC5lbC5zdHlsZS5oZWlnaHQ9KGgubWF4K3dpbmRvdy5pbm5lckhlaWdodC10b3BPZmYpKydweCc7CiAgICAgIH1lbHNle2gubWF4PTA7aC5lbC5zdHlsZS5oZWlnaHQ9Jyd9CiAgICB9KTsKICAgIGhzcy5mb3JFYWNoKGZ1bmN0aW9uKGgpe2gudG9wPWFic1RvcChoLmVsKS10b3BPZmZ9KTsKICAgIGNoYXB0ZXJzPSQkKCdbZGF0YS1jaGFwdGVyXScpLm1hcChmdW5jdGlvbihjKXsKICAgICAgdmFyIHk9bnVsbDsKICAgICAgaHNzLmZvckVhY2goZnVuY3Rpb24oaCl7aWYoaG9yaXomJmgudHJhY2suY29udGFpbnMoYykpeT1oLnRvcCtjLm9mZnNldExlZnR9KTsKICAgICAgaWYoeT09PW51bGwpeT1hYnNUb3AoYyktdG9wT2ZmLTI0OwogICAgICByZXR1cm4ge25hbWU6Yy5nZXRBdHRyaWJ1dGUoJ2RhdGEtY2hhcHRlcicpLHk6TWF0aC5tYXgoMCx5KSxlbDpjfTsKICAgIH0pOwogICAgYnVpbGRCYXIoKTt1cGRhdGUoKTsKICB9CgogIHZhciB0aWNrc0VsPSQoJ1tkYXRhLXRpY2tzXScpLGNoRWw9JCgnW2RhdGEtY2hhcHRlcnNdJyksdG9jRWw9JCgnW2RhdGEtdG9jXScpOwogIHZhciBOPTE0MCx0aWNrcz1bXTsKICBmb3IodmFyIHQ9MDt0PE47dCsrKXt2YXIgcz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7dGlja3NFbC5hcHBlbmRDaGlsZChzKTt0aWNrcy5wdXNoKHMpfQogIGZ1bmN0aW9uIG1heFNjcm9sbCgpe3JldHVybiBNYXRoLm1heCgxLGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQtd2luZG93LmlubmVySGVpZ2h0KX0KICBmdW5jdGlvbiBidWlsZEJhcigpewogICAgY2hFbC5pbm5lckhUTUw9Jyc7dG9jRWwuaW5uZXJIVE1MPScnOwogICAgdGlja3MuZm9yRWFjaChmdW5jdGlvbihzKXtzLmNsYXNzTGlzdC5yZW1vdmUoJ21hcmsnKX0pOwogICAgY2hhcHRlcnMuZm9yRWFjaChmdW5jdGlvbihjLGkpewogICAgICB2YXIgZj1pL2NoYXB0ZXJzLmxlbmd0aDsKICAgICAgdmFyIGI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7Yi50eXBlPSdidXR0b24nO2IudGV4dENvbnRlbnQ9Yy5uYW1lO2Iuc3R5bGUubGVmdD0oZioxMDApKyclJzsKICAgICAgYi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsZnVuY3Rpb24oKXtnbyhjLnkpfSk7Y2hFbC5hcHBlbmRDaGlsZChiKTtjLmJ0bj1iOwogICAgICB0aWNrc1tNYXRoLm1pbihOLTEsTWF0aC5yb3VuZChmKihOLTEpKSldLmNsYXNzTGlzdC5hZGQoJ21hcmsnKTsKICAgICAgdmFyIHRiPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO3RiLnR5cGU9J2J1dHRvbic7CiAgICAgIHRiLmlubmVySFRNTD0nPGI+JytTdHJpbmcoaSsxKS5wYWRTdGFydCgyLCcwJykrJzwvYj4gJytjLm5hbWU7CiAgICAgIHRiLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJyxmdW5jdGlvbigpe2Nsb3NlTWVudSgpO2dvKGMueSl9KTt0b2NFbC5hcHBlbmRDaGlsZCh0Yik7CiAgICB9KTsKICB9CiAgZnVuY3Rpb24gZ28oeSl7d2luZG93LnNjcm9sbFRvKHt0b3A6eSsyLGJlaGF2aW9yOnJlZHVjZT8nYXV0byc6J3Ntb290aCd9KX0KCiAgdmFyIGJsdXJzPSQkKCcuYmx1cmxpbmUnKSx0aWNraW5nPWZhbHNlLGZyYW1lPTA7CiAgZnVuY3Rpb24gdXBkYXRlKCl7CiAgICB0aWNraW5nPWZhbHNlOwogICAgdmFyIHk9d2luZG93LnBhZ2VZT2Zmc2V0LHZoPXdpbmRvdy5pbm5lckhlaWdodDsKICAgIGhzcy5mb3JFYWNoKGZ1bmN0aW9uKGgpewogICAgICBpZighaC5tYXgpcmV0dXJuOwogICAgICB2YXIgcD1NYXRoLm1pbigxLE1hdGgubWF4KDAsKHktaC50b3ApL2gubWF4KSk7CiAgICAgIGgudHJhY2suc3R5bGUudHJhbnNmb3JtPSd0cmFuc2xhdGUzZCgnKygtcCpoLm1heCkudG9GaXhlZCgxKSsncHgsMCwwKSc7CiAgICB9KTsKICAgIHZhciBycj1yb290LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwogICAgdmFyIGJhcnNPbj13aWRlJiZyci50b3A8PXRvcE9mZis4MCYmcnIuYm90dG9tPnZoKi41OwogICAgcm9vdC5jbGFzc0xpc3QudG9nZ2xlKCdiYXJzLW9uJyxiYXJzT24pOwogICAgaWYoKGZyYW1lKyspJTg9PT0wfHxiYXJzT24hPT1pbW1lcnNpdmUpc2V0SW1tZXJzaXZlKGJhcnNPbik7CiAgICBpZighY2hhcHRlcnMubGVuZ3RoKXJldHVybjsKICAgIHZhciBhY3Q9MDtjaGFwdGVycy5mb3JFYWNoKGZ1bmN0aW9uKGMsaSl7aWYoYy55PD15K3ZoKi4zKWFjdD1pfSk7CiAgICB2YXIgYzA9Y2hhcHRlcnNbYWN0XSxjMT1jaGFwdGVyc1thY3QrMV0sZW5kPWMxP2MxLnk6bWF4U2Nyb2xsKCk7CiAgICB2YXIgZnJhYz1jMT8oeSt2aCouMy1jMC55KS9NYXRoLm1heCgxLGVuZC1jMC55KTooeS1jMC55KS9NYXRoLm1heCgxLGVuZC1jMC55KTsKICAgIGZyYWM9TWF0aC5taW4oMSxNYXRoLm1heCgwLGZyYWMpKTsKICAgIHZhciBvbj1NYXRoLnJvdW5kKChhY3QrZnJhYykvY2hhcHRlcnMubGVuZ3RoKk4pOwogICAgZm9yKHZhciBpPTA7aTxOO2krKyl0aWNrc1tpXS5jbGFzc0xpc3QudG9nZ2xlKCdvbicsaTxvbik7CiAgICBjaGFwdGVycy5mb3JFYWNoKGZ1bmN0aW9uKGMsaSl7aWYoYy5idG4pYy5idG4uc2V0QXR0cmlidXRlKCdhcmlhLWN1cnJlbnQnLGk9PT1hY3Q/J3RydWUnOidmYWxzZScpfSk7CiAgICB2YXIgbGJsPSQoJ1tkYXRhLW5vd10nKTtpZihsYmwpbGJsLnRleHRDb250ZW50PWMwLm5hbWU7CiAgICBpZighcmVkdWNlKWJsdXJzLmZvckVhY2goZnVuY3Rpb24oYil7CiAgICAgIHZhciByPWIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICAgIGIuY2xhc3NMaXN0LnRvZ2dsZSgnaXMtYmVsb3cnLHIudG9wPnZoKi43NCk7CiAgICAgIGIuY2xhc3NMaXN0LnRvZ2dsZSgnaXMtYWJvdmUnLHIuYm90dG9tPHZoKi4xNik7CiAgICB9KTsKICB9CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsZnVuY3Rpb24oKXtpZighdGlja2luZyl7dGlja2luZz10cnVlO3JlcXVlc3RBbmltYXRpb25GcmFtZSh1cGRhdGUpfX0se3Bhc3NpdmU6dHJ1ZX0pOwogIHZhciBydDt3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJyxmdW5jdGlvbigpe2NsZWFyVGltZW91dChydCk7cnQ9c2V0VGltZW91dChsYXlvdXQsMTIwKX0pOwoKICB2YXIgdGFyZ2V0cz0kJCgnLnJldmVhbCxbZGF0YS1pbl0nKTsKICBpZignSW50ZXJzZWN0aW9uT2JzZXJ2ZXInIGluIHdpbmRvdyYmIXJlZHVjZSl7CiAgICB2YXIgaW89bmV3IEludGVyc2VjdGlvbk9ic2VydmVyKGZ1bmN0aW9uKGVzKXtlcy5mb3JFYWNoKGZ1bmN0aW9uKGUpe2lmKGUuaXNJbnRlcnNlY3Rpbmcpe2UudGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ2luJyk7aW8udW5vYnNlcnZlKGUudGFyZ2V0KX19KX0se3RocmVzaG9sZDouMTV9KTsKICAgIHRhcmdldHMuZm9yRWFjaChmdW5jdGlvbihlKXtpby5vYnNlcnZlKGUpfSk7CiAgfWVsc2V7dGFyZ2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGUpe2UuY2xhc3NMaXN0LmFkZCgnaW4nKX0pfQoKICAkJCgnW2RhdGEtZ290b10nKS5mb3JFYWNoKGZ1bmN0aW9uKGIpe2IuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGZ1bmN0aW9uKCl7CiAgICB2YXIgZWw9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYi5nZXRBdHRyaWJ1dGUoJ2RhdGEtZ290bycpKTtjbG9zZU1lbnUoKTsKICAgIGlmKCFlbClyZXR1cm47CiAgICB2YXIgYz1udWxsO2NoYXB0ZXJzLmZvckVhY2goZnVuY3Rpb24oY2gpe2lmKGNoLmVsPT09ZWwpYz1jaH0pOwogICAgZ28oYz9jLnk6YWJzVG9wKGVsKS10b3BPZmYtMjQpOwogIH0pfSk7CgogIHZhciBvdj0kKCdbZGF0YS1vdmVybGF5XScpLGxhc3RGb2N1cz1udWxsOwogIGZ1bmN0aW9uIG9wZW5NZW51KCl7bGFzdEZvY3VzPWRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7b3YuaGlkZGVuPWZhbHNlO2RvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5vdmVyZmxvdz0naGlkZGVuJzt2YXIgZj0kKCcuY3YnLG92KTtpZihmKWYuZm9jdXMoKX0KICBmdW5jdGlvbiBjbG9zZU1lbnUoKXtpZihvdi5oaWRkZW4pcmV0dXJuO292LmhpZGRlbj10cnVlO2RvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5vdmVyZmxvdz0nJztpZihsYXN0Rm9jdXMpbGFzdEZvY3VzLmZvY3VzKCl9CiAgJCQoJ1tkYXRhLW9wZW4tbWVudV0nKS5mb3JFYWNoKGZ1bmN0aW9uKGIpe2IuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLG9wZW5NZW51KX0pOwogICQoJ1tkYXRhLWNsb3NlLW1lbnVdJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLGNsb3NlTWVudSk7CiAgb3YuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsZnVuY3Rpb24oZSl7CiAgICBpZihlLmtleT09PSdFc2NhcGUnKXtjbG9zZU1lbnUoKTtyZXR1cm59CiAgICBpZihlLmtleT09PSdUYWInKXt2YXIgZj0kJCgnYnV0dG9uJyxvdiksYT1mWzBdLHo9ZltmLmxlbmd0aC0xXTsKICAgICAgaWYoZS5zaGlmdEtleSYmZG9jdW1lbnQuYWN0aXZlRWxlbWVudD09PWEpe2UucHJldmVudERlZmF1bHQoKTt6LmZvY3VzKCl9CiAgICAgIGVsc2UgaWYoIWUuc2hpZnRLZXkmJmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ9PT16KXtlLnByZXZlbnREZWZhdWx0KCk7YS5mb2N1cygpfX0KICB9KTsKCiAgaWYobWF0Y2hNZWRpYSgnKHBvaW50ZXI6ZmluZSknKS5tYXRjaGVzJiYhcmVkdWNlKXsKICAgIHZhciBjdXI9JCgnLmN1cnNvcicpO3Jvb3QuY2xhc3NMaXN0LmFkZCgnaGFzLWN1cnNvcicpOwogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsZnVuY3Rpb24oZSl7Y3VyLnN0eWxlLnRyYW5zZm9ybT0ndHJhbnNsYXRlM2QoJytlLmNsaWVudFgrJ3B4LCcrZS5jbGllbnRZKydweCwwKSd9LHtwYXNzaXZlOnRydWV9KTsKICAgIHJvb3QuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJyxmdW5jdGlvbihlKXtjdXIuY2xhc3NMaXN0LnRvZ2dsZSgnYmlnJywhIWUudGFyZ2V0LmNsb3Nlc3QoJ2EsYnV0dG9uJykpfSk7CiAgfQoKICByb290LmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLGZ1bmN0aW9uKGUpewogICAgaHNzLmZvckVhY2goZnVuY3Rpb24oaCl7CiAgICAgIGlmKCFoLm1heHx8IWgudHJhY2suY29udGFpbnMoZS50YXJnZXQpKXJldHVybjsKICAgICAgdmFyIHI9ZS50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7CiAgICAgIGlmKHIubGVmdDwwfHxyLnJpZ2h0PndpbmRvdy5pbm5lcldpZHRoKXdpbmRvdy5zY3JvbGxUbyh7dG9wOk1hdGgubWluKGgudG9wK2gubWF4LE1hdGgubWF4KGgudG9wLHdpbmRvdy5wYWdlWU9mZnNldCtyLmxlZnQtODApKX0pOwogICAgfSk7CiAgfSk7CgogIHN0aWNreU9LPXByZXBhcmVBbmNlc3RvcnMoKTsKICBpZihkb2N1bWVudC5mb250cyYmZG9jdW1lbnQuZm9udHMucmVhZHkpZG9jdW1lbnQuZm9udHMucmVhZHkudGhlbihsYXlvdXQpOwogIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJyxsYXlvdXQpOwogIGxheW91dCgpOwogIH0KfSkoKTsKCjsKCi8qIMSQ4bq3dCB0aOG6uyB0w6puIGdp4buvYSBjw6FuaCB0YXkgdGhlbyBrw61jaCB0aMaw4bubYyDhuqNuaCBuaMOibiB24bqtdCAqLwooZnVuY3Rpb24oKXsKICB2YXIgcm9vdD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHZtLW1hZycpO2lmKCFyb290KXJldHVybjsKICB2YXIgaW1nPXJvb3QucXVlcnlTZWxlY3RvcignLmNvdmVyIC5oZXJvLWN1dCcpLHRhZz1yb290LnF1ZXJ5U2VsZWN0b3IoJy5jb3ZlciAubmFtZXN0aWNrZXInKTsKICBpZighaW1nfHwhdGFnKXJldHVybjsKICBmdW5jdGlvbiBwbGFjZSgpewogICAgdmFyIHc9aW1nLm9mZnNldFdpZHRoLGg9aW1nLm9mZnNldEhlaWdodDtpZighd3x8IWgpcmV0dXJuOwogICAgdGFnLnN0eWxlLnNldFByb3BlcnR5KCctLWJ4JywoaW1nLm9mZnNldExlZnQrdyowLjQ3KSsncHgnKTsKICAgIHRhZy5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1ieScsKGltZy5vZmZzZXRUb3AraCood2luZG93LmlubmVyV2lkdGg8PTY0MD8wLjY2OjAuOCkpKydweCcpOwogIH0KICBwbGFjZSgpOwogIGltZy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJyxwbGFjZSk7CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLHBsYWNlKTsKICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJyxwbGFjZSk7CiAgaWYod2luZG93LlJlc2l6ZU9ic2VydmVyKW5ldyBSZXNpemVPYnNlcnZlcihwbGFjZSkub2JzZXJ2ZShpbWcpOwp9KSgpOwo=")