Ch.5 Communicating, Sharing, Collaborating Procedure
Question

What feature makes co-editing safer than exchanging attachments?

Tap to reveal answer
Deep dive

Version history: why co-editing beats attachments

Version history with tracked changes and recoverable previous states. The main trap is confusing 'track changes' with 'version history'.

Learn more
Listen to this page (beta)

View all flashcards
(function(){ var players = document.querySelectorAll('[data-audio-captions][data-captions-url]'); var parseTimestamp = function(value) { var parts = value.trim().split(':'); var seconds = parts.pop() || '0'; var minutes = parts.pop() || '0'; var hours = parts.pop() || '0'; return (Number(hours) * 3600) + (Number(minutes) * 60) + Number(seconds.replace(',', '.')); }; var parseCues = function(text) { return text .replace(/\r/g, '') .split(/\n\n+/) .map(function(block) { return block.split('\n').filter(Boolean); }) .filter(function(lines) { return lines.length >= 2 && lines[0] !== 'WEBVTT'; }) .map(function(lines) { if (!lines[0].includes('-->')) { lines.shift(); } var timing = lines.shift() || ''; var parts = timing.split('-->').map(function(part) { return part.trim(); }); return { start: parseTimestamp(parts[0] || '0'), end: parseTimestamp(parts[1] || '0'), text: lines.join(' '), }; }) .filter(function(cue) { return Number.isFinite(cue.start) && Number.isFinite(cue.end) && cue.text !== ''; }); }; var findCue = function(cues, time) { return cues.find(function(cue) { return time >= cue.start && time < cue.end; }) || cues.find(function(cue) { return time < cue.start; }) || cues[cues.length - 1] || null; }; players.forEach(function(player) { var audio = player.querySelector('audio'); var output = player.querySelector('[data-audio-captions-output]'); if (!audio || !output) { return; } fetch(player.dataset.captionsUrl) .then(function(response) { return response.ok ? response.text() : ''; }) .then(function(text) { var cues = parseCues(text); var activeText = ''; var render = function() { var cue = findCue(cues, audio.currentTime); if (!cue || cue.text === activeText) { return; } activeText = cue.text; output.textContent = cue.text; }; render(); audio.addEventListener('timeupdate', render); audio.addEventListener('seeked', render); audio.addEventListener('play', render); }); }); })();