Files
2026-03-21 01:15:26 -07:00

213 lines
13 KiB
HTML

<div v-if="activeTab === 'splitter'" class="tab-content">
<div class="transform-layout">
<div class="transform-section">
<div class="section-header-card">
<div class="section-header-card-title">
<i class="fas fa-grip-lines"></i>
<h3>Message Splitter</h3>
</div>
<p class="section-header-card-description">Split text into multiple copyable chunks. Each message can be transformed and encapsulated individually.</p>
</div>
<!-- Input Section -->
<div class="input-section">
<textarea
id="splitter-input"
v-model="splitterInput"
placeholder="Enter text to split into messages..."
rows="4"
></textarea>
</div>
<!-- Options Section -->
<div class="options-grid">
<label>
Mode
<select v-model="splitterMode">
<option value="chunk">Character Chunks</option>
<option value="word">Split Words</option>
<option value="sentence">Sentences</option>
<option value="line">Lines</option>
<option value="pattern">Custom Pattern (Regex)</option>
<option value="token">Token-Based</option>
</select>
</label>
<!-- Character chunk options -->
<label v-if="splitterMode === 'chunk'">
Chunk Size
<input type="number" v-model.number="splitterChunkSize" min="1" max="500" placeholder="6" />
</label>
<!-- Word split options -->
<label v-if="splitterMode === 'word'">
Split Side (odd length)
<select v-model="splitterWordSplitSide">
<option value="left">Left (larger first half)</option>
<option value="right">Right (larger second half)</option>
</select>
</label>
<label v-if="splitterMode === 'word'">
Words to Skip
<input type="number" v-model.number="splitterWordSkip" min="0" max="20" placeholder="0" />
</label>
<label v-if="splitterMode === 'word'">
Min Word Length
<input type="number" v-model.number="splitterMinWordLength" min="1" placeholder="2" />
</label>
<label v-if="splitterMode === 'word'" class="switch neon">
<input type="checkbox" v-model="splitterSplitFirstWord" />
<span>Split First Word</span>
</label>
<!-- Sentence mode options -->
<label v-if="splitterMode === 'sentence'" class="switch neon">
<input type="checkbox" v-model="splitterPreserveEmptyLines" />
<span>Preserve Empty Lines</span>
</label>
<!-- Line mode options -->
<label v-if="splitterMode === 'line'" class="switch neon">
<input type="checkbox" v-model="splitterPreserveEmptyLines" />
<span>Preserve Empty Lines</span>
</label>
<!-- Custom pattern options -->
<label v-if="splitterMode === 'pattern'">
Regex Pattern
<input type="text" v-model="splitterCustomPattern" placeholder="\\s+" />
</label>
<label v-if="splitterMode === 'pattern'" class="switch neon">
<input type="checkbox" v-model="splitterPatternIncludeDelimiter" />
<span>Include Delimiter</span>
</label>
<!-- Token-based options -->
<label v-if="splitterMode === 'token'">
Tokenizer
<select v-model="splitterTokenizer">
<option value="cl100k">cl100k (GPT-3.5/GPT-4)</option>
<option value="o200k">o200k (GPT-4o)</option>
<option value="p50k">p50k (Code editing models)</option>
<option value="r50k">r50k (GPT-2/GPT-3)</option>
</select>
</label>
<label v-if="splitterMode === 'token'">
Tokens Per Chunk
<input type="number" v-model.number="splitterTokenCount" min="1" max="1000" placeholder="3" />
</label>
</div>
<!-- Transform Section -->
<div class="transform-section">
<div class="section-header">
<h4><i class="fas fa-magic"></i> Transform</h4>
<p>Apply transformations to each split message individually. Transformations are applied in sequence.</p>
</div>
<div class="transform-chain">
<div class="transform-chain-inline">
<div v-for="(transform, index) in splitterTransforms" :key="'transform-'+index" class="transform-chain-item">
<select v-model="splitterTransforms[index]" @change="handleTransformChange(index)">
<option value="">None</option>
<optgroup v-if="getFavoriteTransforms().length > 0" label="⭐ Favorites">
<option v-for="t in getFavoriteTransforms()" :key="t.name" :value="t.name">
{{ t.name }}
</option>
</optgroup>
<optgroup
v-for="category in categoryOrder"
:key="category"
:label="getCategoryDisplayName(category)"
v-if="getTransformsByCategory(category).length > 0"
>
<option
v-for="t in getTransformsByCategory(category)"
:key="t.name"
:value="t.name"
>
{{ t.name }}
</option>
</optgroup>
</select>
<i v-if="index < splitterTransforms.length - 1" class="fas fa-arrow-right transform-arrow"></i>
</div>
</div>
</div>
</div>
<!-- Encapsulation Options -->
<div class="encapsulation-section">
<div class="section-header">
<h4><i class="fas fa-bracket-curly"></i> Encapsulation</h4>
<p>Wrap each message with custom start and end strings. Use iterator marker to insert split numbers.</p>
</div>
<div class="options-grid">
<label>
Iterator Marker
<input type="text" v-model="splitterIteratorMarker" placeholder="{n}" />
<small>This marker will be replaced with the split number (1, 2, 3...)</small>
</label>
<label>
Start String (optional)
<input type="text" v-model="splitterStartWrap" placeholder="e.g., Message {n}: " />
</label>
<label>
End String (optional)
<input type="text" v-model="splitterEndWrap" placeholder="e.g., $, >, ]" />
</label>
</div>
<div class="encapsulation-presets">
<small>Quick presets:</small>
<button @click="setEncapsulation('$', '$')" class="preset-btn">$...$</button>
<button @click="setEncapsulation('<', '>')" class="preset-btn">&lt;...&gt;</button>
<button @click="setEncapsulation('[', ']')" class="preset-btn">[...]</button>
<button @click="setEncapsulation('(', ')')" class="preset-btn">(...)</button>
<button @click="setEncapsulation('{', '}')" class="preset-btn">{...}</button>
<button @click="setEncapsulation('`', '`')" class="preset-btn">`...`</button>
<button @click="setEncapsulation('&quot;', '&quot;')" class="preset-btn">&quot;...&quot;</button>
<button @click="setEncapsulation('', '')" class="preset-btn">Clear</button>
</div>
</div>
<!-- Generate Button -->
<div class="tool-toolbar">
<button type="button" class="transform-button tool-primary-btn" @click="generateSplitMessages">
<i class="fas fa-cut"></i> Split Messages
</button>
<button class="action-button copy" v-if="splitMessages.length" @click="copyAllSplitMessages">
<i class="fas fa-copy"></i> Copy All
</button>
<label v-if="splitMessages.length" class="switch neon splitter-copy-option">
<input type="checkbox" v-model="splitterCopyAsSingleLine" />
<span>Single Line</span>
</label>
</div>
<!-- Output Section -->
<div class="output-section split-messages-container" v-if="splitMessages.length">
<div class="output-heading">
<h4>
<i class="fas fa-list"></i> Split Messages
<small>{{ splitMessages.length }} message{{ splitMessages.length !== 1 ? 's' : '' }}</small>
</h4>
</div>
<div class="split-messages-grid">
<div v-for="(msg, index) in splitMessages" :key="index" class="split-message-card">
<div class="split-message-header">
<span class="message-number">Message {{ index + 1 }}</span>
<button class="copy-button-small" @click="copyToClipboard(msg)" title="Copy this message">
<i class="fas fa-copy"></i>
</button>
</div>
<div class="split-message-content">{{ msg }}</div>
</div>
</div>
</div>
</div>
</div>
</div>