Image-Text-to-Text
Transformers
Safetensors
PyTorch
English
qwen3_5
decision-model
text-generation-inference
SFT
image-classification
OneDecision
VisionGuard
JSON
content-safety
content-moderation
multimodal
safety-classifier
guardrail
visual-safety
multimodal-content-filter
uncensored
conversational
Instructions to use prithivMLmods/OneDecision-VisionGuard-9B-SFT with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use prithivMLmods/OneDecision-VisionGuard-9B-SFT with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="prithivMLmods/OneDecision-VisionGuard-9B-SFT") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("prithivMLmods/OneDecision-VisionGuard-9B-SFT") model = AutoModelForMultimodalLM.from_pretrained("prithivMLmods/OneDecision-VisionGuard-9B-SFT", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use prithivMLmods/OneDecision-VisionGuard-9B-SFT with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "prithivMLmods/OneDecision-VisionGuard-9B-SFT" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "prithivMLmods/OneDecision-VisionGuard-9B-SFT", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/prithivMLmods/OneDecision-VisionGuard-9B-SFT
- SGLang
How to use prithivMLmods/OneDecision-VisionGuard-9B-SFT with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "prithivMLmods/OneDecision-VisionGuard-9B-SFT" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "prithivMLmods/OneDecision-VisionGuard-9B-SFT", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "prithivMLmods/OneDecision-VisionGuard-9B-SFT" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "prithivMLmods/OneDecision-VisionGuard-9B-SFT", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use prithivMLmods/OneDecision-VisionGuard-9B-SFT with Docker Model Runner:
docker model run hf.co/prithivMLmods/OneDecision-VisionGuard-9B-SFT
Commit ·
c025890
1
Parent(s): 4c24e42
Update README.md
Browse files
README.md
CHANGED
|
@@ -1,175 +0,0 @@
|
|
| 1 |
-
---
|
| 2 |
-
tags:
|
| 3 |
-
- text-generation-inference
|
| 4 |
-
---
|
| 5 |
-
<!DOCTYPE html>
|
| 6 |
-
<html lang="en">
|
| 7 |
-
<head>
|
| 8 |
-
<meta charset="utf-8">
|
| 9 |
-
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
| 10 |
-
<title>OneDecision-VisionGuard-9B-SFT workflow</title>
|
| 11 |
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&family=JetBrains+Mono:wght@500&display=swap">
|
| 12 |
-
<style>
|
| 13 |
-
:root{--page:#e6e6e6;box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}
|
| 14 |
-
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--page:#000}}
|
| 15 |
-
:root[data-theme="dark"]{--page:#000}
|
| 16 |
-
html{scroll-padding-top:env(safe-area-inset-top,0px)}
|
| 17 |
-
*{box-sizing:border-box}
|
| 18 |
-
body{margin:0;padding:16px;background:var(--page);font-family:"Space Grotesk",system-ui,sans-serif}
|
| 19 |
-
#wrap{position:relative;width:100%;max-width:1280px;margin:0 auto;overflow:hidden;border-radius:28px}
|
| 20 |
-
#stage{--bg:#000;--bx:#0b0b0b;--ln:#262626;--mut:#7d7d7d;--safe:#3ddc97;--bad:#ff5a6a;
|
| 21 |
-
position:absolute;left:0;top:0;width:1280px;height:720px;transform-origin:0 0;background:var(--bg);color:#f2f2f2;overflow:hidden}
|
| 22 |
-
.bx{position:absolute;background:var(--bx);border:1px solid var(--ln);border-radius:28px;overflow:hidden}
|
| 23 |
-
.t{position:absolute;left:24px;top:20px;font-size:18px;font-weight:500;color:var(--mut)}
|
| 24 |
-
.img{position:absolute;inset:0;background-size:cover;background-position:center}
|
| 25 |
-
.img.blur{filter:blur(36px);transform:scale(1.4)}
|
| 26 |
-
.pic,.tok{position:absolute;left:90px;top:176px;width:240px;height:240px;border-radius:20px;overflow:hidden;background:#161616}
|
| 27 |
-
.pic{transition:opacity .5s}
|
| 28 |
-
.tok{z-index:5;opacity:0;border:1px solid var(--ln)}
|
| 29 |
-
#head{left:40px;top:32px;height:60px;padding:0 26px;display:flex;align-items:center;gap:14px;border-radius:999px;white-space:nowrap;font-size:26px;font-weight:700;letter-spacing:-.3px}
|
| 30 |
-
#model .nm{position:absolute;left:24px;top:20px;display:flex;gap:12px;align-items:center}
|
| 31 |
-
#model .nm b{display:block;font-size:22px;line-height:1.1}
|
| 32 |
-
#model .nm span{display:block;font-size:14px;color:var(--mut);margin-top:3px}
|
| 33 |
-
.scan{position:absolute;left:24px;right:24px;top:190px;height:3px;border-radius:3px;background:#fff;opacity:0}
|
| 34 |
-
#model.scanning .scan{opacity:.9;animation:sc 1s ease-in-out infinite alternate}
|
| 35 |
-
@keyframes sc{from{top:196px}to{top:340px}}
|
| 36 |
-
@media (prefers-reduced-motion:reduce){#model.scanning .scan{animation:none;top:270px}}
|
| 37 |
-
.chip{position:absolute;left:50%;bottom:20px;transform:translateX(-50%);padding:7px 20px;border-radius:999px;font-size:16px;font-weight:700;background:#1a1a1a;color:var(--mut);white-space:nowrap}
|
| 38 |
-
.chip.run{background:#fff;color:#000}.chip.safe{background:var(--safe);color:#04170e}.chip.bad{background:var(--bad);color:#2a0409}
|
| 39 |
-
.hd{position:absolute;left:24px;right:24px;top:18px;display:flex;align-items:center;gap:10px;font-size:20px;font-weight:700}
|
| 40 |
-
.hd small{font-size:14px;font-weight:500;color:var(--mut)}
|
| 41 |
-
.hd i{margin-left:auto;font-style:normal}
|
| 42 |
-
#pass .hd{color:var(--safe)}#dump .hd{color:var(--bad)}
|
| 43 |
-
.cap{position:absolute;right:24px;bottom:24px;font-size:15px;color:var(--mut);white-space:nowrap}
|
| 44 |
-
.minis{position:absolute;left:20px;bottom:20px;display:flex;gap:12px}
|
| 45 |
-
.mini{position:relative;width:64px;height:64px;border-radius:16px;overflow:hidden;border:1px solid var(--ln);animation:pop .35s}
|
| 46 |
-
@keyframes pop{from{transform:scale(.6);opacity:0}}
|
| 47 |
-
svg.fl{position:absolute;left:0;top:0;width:1280px;height:720px;pointer-events:none}
|
| 48 |
-
.pa{stroke:var(--ln);fill:none;stroke-width:2;stroke-linecap:round;stroke-dasharray:5 8}
|
| 49 |
-
.pa.on{animation:fl .8s linear infinite;stroke:#fff}.pa.on.s{stroke:var(--safe)}.pa.on.b{stroke:var(--bad)}
|
| 50 |
-
@keyframes fl{to{stroke-dashoffset:-13}}
|
| 51 |
-
#json{position:absolute;left:24px;top:58px;font-family:"JetBrains Mono",ui-monospace,monospace;font-size:16px;line-height:1.5;white-space:pre;color:#cfcfcf}
|
| 52 |
-
#json b{font-weight:500}.g{color:var(--safe)}.r{color:var(--bad)}
|
| 53 |
-
#why{position:absolute;left:310px;right:24px;top:58px;font-size:17px;line-height:1.5;color:#e6e6e6;opacity:0;transition:opacity .5s}
|
| 54 |
-
#why.show{opacity:1}#why small{display:block;color:var(--mut);font-size:14px;margin-bottom:6px}
|
| 55 |
-
.th{position:absolute;top:84px;width:64px;height:64px;border-radius:16px;overflow:hidden;border:2px solid var(--ln);cursor:pointer;padding:0;background:#161616}
|
| 56 |
-
.th.act{border-color:#fff}
|
| 57 |
-
.th:focus-visible{outline:3px solid #fff;outline-offset:3px}
|
| 58 |
-
</style>
|
| 59 |
-
</head>
|
| 60 |
-
<body>
|
| 61 |
-
<div id="wrap">
|
| 62 |
-
<div id="stage">
|
| 63 |
-
<div class="bx" id="head">
|
| 64 |
-
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.800" stroke-linejoin="round"><path d="M12 2 4 5v6c0 5 3.400 9.400 8 11 4.600-1.600 8-6 8-11V5z"/><circle cx="12" cy="11" r="2.500"/></svg>
|
| 65 |
-
OneDecision-VisionGuard-9B-SFT
|
| 66 |
-
</div>
|
| 67 |
-
|
| 68 |
-
<svg class="fl" viewBox="0 0 1280 720">
|
| 69 |
-
<path id="p1" class="pa" d="M380 296H460"/>
|
| 70 |
-
<path id="p2" class="pa" d="M760 296C800 296 800 195 840 195"/>
|
| 71 |
-
<path id="p3" class="pa" d="M760 296C800 296 800 365 840 365"/>
|
| 72 |
-
</svg>
|
| 73 |
-
|
| 74 |
-
<div class="bx" style="left:40px;top:120px;width:340px;height:320px"><div class="t">Input</div></div>
|
| 75 |
-
<div class="pic" id="inCard"><div class="img" id="inImg"></div></div>
|
| 76 |
-
|
| 77 |
-
<div class="bx" id="model" style="left:460px;top:120px;width:300px;height:320px">
|
| 78 |
-
<div class="nm">
|
| 79 |
-
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.800" stroke-linejoin="round"><path d="M12 2 4 5v6c0 5 3.400 9.400 8 11 4.600-1.600 8-6 8-11V5z"/><circle cx="12" cy="11" r="2.500"/></svg>
|
| 80 |
-
<div><b>VisionGuard</b><span>9B parameters, SFT</span></div>
|
| 81 |
-
</div>
|
| 82 |
-
<div class="scan"></div>
|
| 83 |
-
<div class="chip" id="chip">Waiting</div>
|
| 84 |
-
</div>
|
| 85 |
-
|
| 86 |
-
<div class="bx" id="pass" style="left:840px;top:120px;width:400px;height:150px;border-color:#1f6b4b">
|
| 87 |
-
<div class="hd"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.200" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9.500"/><path d="m7.500 12.500 3 3 6-6.500"/></svg>Passed <small>safe = 1</small><i id="pc">0</i></div>
|
| 88 |
-
<div class="minis" id="pm"></div><div class="cap">Released downstream</div>
|
| 89 |
-
</div>
|
| 90 |
-
<div class="bx" id="dump" style="left:840px;top:290px;width:400px;height:150px;border-color:#7a2a33">
|
| 91 |
-
<div class="hd"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.200" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h16M9 7V4h6v3M6.500 7l1 13h9l1-13M10 11v6M14 11v6"/></svg>Dumped <small>nsfw = 1</small><i id="dc">0</i></div>
|
| 92 |
-
<div class="minis" id="dm"></div><div class="cap">Blocked and discarded</div>
|
| 93 |
-
</div>
|
| 94 |
-
|
| 95 |
-
<div class="tok" id="tok"><div class="img" id="tokImg"></div></div>
|
| 96 |
-
|
| 97 |
-
<div class="bx" style="left:40px;top:470px;width:340px;height:200px"><div class="t">Examples</div><div id="ths"></div></div>
|
| 98 |
-
|
| 99 |
-
<div class="bx" style="left:460px;top:470px;width:780px;height:200px">
|
| 100 |
-
<div class="t">Model output</div>
|
| 101 |
-
<div id="json"></div>
|
| 102 |
-
<div id="why"><small>Reasoning</small><span id="rs"></span></div>
|
| 103 |
-
</div>
|
| 104 |
-
</div>
|
| 105 |
-
</div>
|
| 106 |
-
|
| 107 |
-
<script>
|
| 108 |
-
const B='https://cdn-uploads.huggingface.co/production/uploads/65bb837dbfb878f46c77de4c/';
|
| 109 |
-
const S=[
|
| 110 |
-
{u:B+'BruPdRkcmco3HUoTQLd9v.jpeg',nsfw:0,g:'linear-gradient(135deg,#7a2a22,#b88a2e 55%,#141414)',r:'Fully armored superhero in a combat scene. No nudity, no suggestive posing.'},
|
| 111 |
-
{u:B+'LHoPgdJUuuNVXRpdAGwZf.jpeg',nsfw:1,g:'linear-gradient(135deg,#8a6a7e,#5b4670 60%,#141414)',r:'Revealing lingerie and a sexually suggestive pose.'},
|
| 112 |
-
{u:B+'64bLutLTC6HUlvAyiFKLH.jpeg',nsfw:0,g:'linear-gradient(135deg,#6f86ad,#3a5278 60%,#141414)',r:'Casual button-down shirt with full coverage and a neutral expression.'},
|
| 113 |
-
{u:B+'yLwGYwcg7UfZSnXbYFWZh.jpeg',nsfw:1,g:'linear-gradient(135deg,#a07c6c,#7a4658 60%,#141414)',r:'Revealing lingerie and an alluring pose.'}
|
| 114 |
-
];
|
| 115 |
-
const $=id=>document.getElementById(id),sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
| 116 |
-
const fill=(el,s)=>{el.style.backgroundImage=`url("${s.u}"),${s.g}`;el.classList.toggle('blur',!!s.nsfw)};
|
| 117 |
-
const wrap=$('wrap'),st=$('stage'),tok=$('tok'),model=$('model'),chip=$('chip');
|
| 118 |
-
function fit(){const k=wrap.clientWidth/1280;st.style.transform=`scale(${k})`;wrap.style.height=720*k+'px'}
|
| 119 |
-
new ResizeObserver(fit).observe(wrap);fit();
|
| 120 |
-
document.querySelectorAll('#pass,#dump').forEach(e=>e.style.height='150px');
|
| 121 |
-
|
| 122 |
-
const ths=S.map((s,i)=>{const b=document.createElement('button');b.className='th';b.style.left=24+i*76+'px';
|
| 123 |
-
b.setAttribute('aria-label','Run example '+(i+1));b.innerHTML='<div class="img"></div>';fill(b.firstChild,s);
|
| 124 |
-
b.onclick=()=>play(i,true);$('ths').appendChild(b);return b});
|
| 125 |
-
|
| 126 |
-
let run=0,n={p:0,d:0};
|
| 127 |
-
const setChip=(t,c)=>{chip.textContent=t;chip.className='chip '+c};
|
| 128 |
-
const paths=[$('p1'),$('p2'),$('p3')];
|
| 129 |
-
function clearBoxes(){n={p:0,d:0};$('pm').innerHTML='';$('dm').innerHTML='';$('pc').textContent=0;$('dc').textContent=0}
|
| 130 |
-
function addMini(box,s,bad){const m=document.createElement('div');m.className='mini';m.innerHTML='<div class="img"></div>';
|
| 131 |
-
if(bad)m.style.borderColor='#7a2a33';fill(m.firstChild,s);$(box).appendChild(m)}
|
| 132 |
-
|
| 133 |
-
async function play(i,fresh){
|
| 134 |
-
const id=++run,s=S[i],ok=()=>id===run,safe=!s.nsfw;
|
| 135 |
-
if(fresh)clearBoxes();
|
| 136 |
-
ths.forEach((t,k)=>t.classList.toggle('act',k===i));
|
| 137 |
-
fill($('inImg'),s);$('inCard').style.opacity=1;
|
| 138 |
-
tok.style.transition='none';tok.style.opacity=0;tok.style.transform='none';
|
| 139 |
-
paths.forEach(p=>p.setAttribute('class','pa'));
|
| 140 |
-
model.classList.remove('scanning');setChip('Waiting','');
|
| 141 |
-
$('json').innerHTML='';$('why').classList.remove('show');
|
| 142 |
-
await sleep(800);if(!ok())return;
|
| 143 |
-
|
| 144 |
-
fill($('tokImg'),s);void tok.offsetWidth;
|
| 145 |
-
tok.style.transition='transform .9s cubic-bezier(.6,0,.3,1),opacity .4s';tok.style.opacity=1;
|
| 146 |
-
paths[0].setAttribute('class','pa on');$('inCard').style.opacity=.25;
|
| 147 |
-
tok.style.transform='translate(400px,0) scale(.42)';
|
| 148 |
-
await sleep(1000);if(!ok())return;
|
| 149 |
-
|
| 150 |
-
model.classList.add('scanning');setChip('Analyzing','run');
|
| 151 |
-
await sleep(1600);if(!ok())return;
|
| 152 |
-
model.classList.remove('scanning');
|
| 153 |
-
setChip(safe?'Safe':'NSFW',safe?'safe':'bad');
|
| 154 |
-
paths[safe?1:2].setAttribute('class','pa on '+(safe?'s':'b'));
|
| 155 |
-
|
| 156 |
-
const a=s.nsfw?'r':'g',z=safe?'g':'r';
|
| 157 |
-
const L=[` "is_nsfw": <b class="${a}">${!!s.nsfw}</b>,`,` "nsfw": <b class="${a}">${s.nsfw}</b>,`,` "safe": <b class="${z}">${1-s.nsfw}</b>`];
|
| 158 |
-
let h='{\n';$('json').innerHTML=h;
|
| 159 |
-
for(const l of L){await sleep(240);if(!ok())return;h+=l+'\n';$('json').innerHTML=h}
|
| 160 |
-
$('json').innerHTML=h+'}';
|
| 161 |
-
$('rs').textContent=s.r;$('why').classList.add('show');
|
| 162 |
-
await sleep(900);if(!ok())return;
|
| 163 |
-
|
| 164 |
-
const k=safe?n.p:n.d,cx=892+76*k,cy=safe?218:388;
|
| 165 |
-
tok.style.transform=`translate(${cx-210}px,${cy-296}px) scale(.267)`;
|
| 166 |
-
await sleep(1000);if(!ok())return;
|
| 167 |
-
addMini(safe?'pm':'dm',s,!safe);tok.style.opacity=0;
|
| 168 |
-
if(safe){n.p++;$('pc').textContent=n.p}else{n.d++;$('dc').textContent=n.d}
|
| 169 |
-
await sleep(2000);if(!ok())return;
|
| 170 |
-
const nx=(i+1)%S.length;play(nx,nx===0);
|
| 171 |
-
}
|
| 172 |
-
play(0,true);
|
| 173 |
-
</script>
|
| 174 |
-
</body>
|
| 175 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|