関連文書この記事の一部は、https://www.cnblogs.com/zhongchao666/p/11142537.html から参照されています。 Tinymce 中国語ドキュメント: http://tinymce.ax-z.cn/ TinyMCEをインストールする1. 関連する依存関係をインストールする yarn に tinymce を追加 || npm に tinymce をインストール -S 糸を @tinymce/tinymce-vue に追加します || npm をインストールします @tinymce/tinymce-vue -S 2. 中国語エディタ 中国語パッケージをダウンロードするには、次のアドレスにアクセスしてください: https://www.tiny.cloud/get-tiny/language-packages/ プロジェクトのパブリックフォルダに新しいtinymceフォルダを作成し、ダウンロードした圧縮パッケージをこのフォルダに解凍し、node_modules/tinymce/skinsフォルダをpublic/tinymceにコピーします。 3. コンポーネントをカプセル化する: src/components の下に新しい TEditor.vue を作成し、次のコードを記述します。 <テンプレート> <div class="tinymce-box"> <エディター v-model="contentValue" :init="init" :disabled="無効" @onClick="onClick" /> </div> </テンプレート> <スクリプト> '../api/api.js' から api をインポートします //TinyMCE エディタをインポートする import Editor from '@tinymce/tinymce-vue' // node_modules に tinymce 関連ファイルを導入import tinymce from 'tinymce/tinymce' //tinymce はデフォルトで非表示になっており、インポートしないとエディターは表示されませんimport 'tinymce/themes/silver' //エディター テーマ。インポートしないとエラーが報告されますimport 'tinymce/icons/default' //エディター アイコンを導入します。インポートしないと、対応するアイコンは表示されません//エディター プラグインを導入します (基本的な無料プラグインはすべてここにあります) : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 名前: 'TEditor'、 コンポーネント: エディタ }, 小道具: { 価値: { タイプ: 文字列、 デフォルト: '' }, 無効: タイプ: ブール値、 デフォルト: false }, プラグイン: { タイプ: [文字列、配列], デフォルト: '印刷プレビュー、検索、置換、自動リンク、方向性、ビジュアルブロック、ビジュアル文字、全画面、画像、リンク、メディア、テンプレート、コード、コードサンプル、表、チャームマップ、hr、改ページ、非改行、アンカー、挿入、日付、時刻、広告リスト、リスト、単語数、テキストパターン、自動保存' }, ツールバー: タイプ: [文字列、配列], デフォルト: '全画面 元に戻す やり直し 復元 ラフト | 切り取り コピー 貼り付け 貼り付けテキスト | 前景色 背景色 太字 斜体 下線 取り消し線 リンク アンカー | 左揃え 中央揃え 右揃え 両端揃え アウトデント インデント | \ スタイル選択 フォーマット選択 フォント選択 フォントサイズ選択 | 箇条書き 数値リスト | 引用ブロック 下付き文字 上付き文字 削除フォーマット | \ テーブル イメージ メディア チャーマップ hr 改ページ挿入日時 印刷プレビュー | コード すべて選択 検索置換 ビジュアルブロック | インデント 2em 行の高さ フォーマット ペインター axupimgs' }, }, データ(){ 戻る { 初期化: { language_url: '/tinymce/langs/zh_CN.js', //言語パック ファイルを導入language: 'zh_CN', //言語の種類kin_url: '/tinymce/skins/ui/oxide', //スキン: 明るい色//skin_url: '/tinymce/skins/ui/oxide-dark', //スキン: 暗い色plugins: this.plugins, //プラグインの設定toolbar: this.toolbar, //ツールバーの設定。非表示にするには false に設定します//menubar: 'file edit', //メニュー バーの設定。非表示にするには false に設定します。設定されていない場合は、すべてのメニューがデフォルトで表示されます。設定をカスタマイズすることもできます。http://tinymce.ax-z.cn/configure/editor-appearance.php を参照してください。--「カスタム メニュー」を検索します : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : height: 400, //注: このプロパティは、自動サイズ変更プラグインが導入されると無効になります。placeholder: 'ここにテキストを入力してください', : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : paste_data_images: true, // 画像を貼り付けることができますか? images_upload_handler: (blobInfo, success, failure) => { if(blobInfo.blob().size/1024/1024>2){ 失敗("アップロードに失敗しました。画像サイズは 2M 以内にしてください") }それ以外{ パラメータ = new FormData() とする params.append('ファイル',blobInfo.blob()) config={を設定します ヘッダー:{ "コンテンツタイプ":"マルチパート/フォームデータ" } } this.$axios.post(`${api.baseUrl}/api-upload/uploadimg`,params,config).then(res=>{ res.data.code==200の場合{ success(res.data.msg) //アップロードに成功しました。成功関数に画像パスを入力してください}else{ 失敗("アップロードに失敗しました") } }).catch(()=>{ 失敗("アップロードエラー、サーバーがダウンしています") }) } } }, コンテンツ値: this.value } }, 時計: 値 (新しい値) { this.contentValue = 新しい値 }, コンテンツ値 (新しい値) { this.$emit('input', 新しい値) }, }, 作成された(){ }, マウントされた(){ tinymce.init({}) }, メソッド: { // 関連イベントを追加します。利用可能なイベントについてはドキュメントを参照してください => https://github.com/tinymce/tinymce-vue => 利用可能なすべてのイベント クリックすると this.$emit('onClick', e, tinymce) }, // コンテンツをクリアする clear(){ this.contentValue = '' }, }, } </スクリプト> <スタイル lang="less"> </スタイル> コンポーネントの登録と使用 main.js でグローバルに登録します。 import TEditor from '@/components/TEditor.vue' Vue.component('TEditor',TEditor) 関連ページでは <TEditor ref="editor" v-model="value" /> を使用します 注意:単一画像アップロードプラグインの呼び出しインターフェースは異なります。画像のアップロードとファイルのアップロードの両方の機能が呼び出されるため、ファイルのアップロード機能に画像アップロードの判断と処理も追加する必要があります。 絵文字プラグインを正常に読み込めませんでしたインポートパスに問題があり、ファイルパッケージをインポートできないため、次のエラーが発生します。パスを自分で設定する必要があります。 キャッチされない構文エラー: 予期しないトークン '<' 絵文字の読み込みに失敗しました: URL のスクリプト 「http://xxxx/static/js/plugins/emoticons/js/emojis.js」は呼び出されませんでした 1秒以内に`tinymce.Resource.add('tinymce.plugins.emoticons', data)` 回避策 1. node_modules/tinymce/plugins/emoticonsフォルダをpublic/tinymceにコピーします。 2. 上記のコードのinitにemoticons_database_url:'/tinymce/emoticons/js/emojis.js'というコード行を追加します。図を参照してください。 3. 上記のコードでプラグインとツールバーに絵文字を追加して、表現プラグインを導入します。図を参照してください。 4. プロジェクトを更新または再起動する 最初の行のインデント機能を追加参考資料: http://tinymce.ax-z.cn/more-plugins/indent2em.php 1. 上記のドキュメントにアクセスして、intent2em プラグインをダウンロードします。 2. 図 3 に示すように、解凍した最初の行のインデント プラグイン intent2em を public/tinymce フォルダーにコピーします。 indent2em に新しい index.js を作成し、次のコードを記述します // モジュール ローダーで使用するために "indent2em" プラグインをエクスポートします // 使用法: // 共通JS: // 'tinymce/plugins/indent2em' が必要です // ES2015: // 'tinymce/plugins/indent2em' をインポートします './plugin.js' が必要です。 4. components/TEditor.vueに最初の行のインデントプラグインをインポートし、図に示すようにプラグインとツールバーにプラグインを登録します。 import '../../public/tinymce/indent2em' //最初の行のインデント 5. プロジェクトを更新または再起動して使用します。 書式ペインター 方法は最初の行のインデント機能と同じです CSS導入時の警告問題を解決する 解決する プロジェクトパスの展開により、以前のデフォルトの CSS インポートに問題が発生し、警告が報告される可能性があるため、以前のものを置き換える CSS をインポートすることをお勧めします。1. public/tinymce フォルダーに新しい tinycontent.css を作成します。 2. src/components/TEditor.vue の init で tinycontent.css をインポートし、content_style をコメントアウトします (css ファイルが導入されているため、content_style フィールドは必要ありません) content_css: `${api.editorUrl}tinymce/tinycontent.css`, // 編集可能領域の CSS スタイルを CSS ファイルの形式でカスタマイズします。CSS ファイルは自分で作成してインポートする必要があります。3. プロジェクトを更新または再起動すると、警告は消えます。 複数画像アップロード機能を実装参考資料: http://tinymce.ax-z.cn/more-plugins/axupimgs.php 1. 上記のドキュメントにアクセスし、マルチ画像アップロードプラグインaxupimgsをダウンロードします。 2. 解凍したマルチ画像アップロードプラグイン axupimgs を public/tinymce フォルダにコピーします 3. axupimgs フォルダに新しい index.js を作成し、次のコードを記述します // モジュールローダーで使用するために「axupimgs」プラグインをエクスポートします // 使用法: // 共通JS: // 'tinymce/plugins/axupimgs' が必要です // ES2015: // 'tinymce/plugins/axupimgs' をインポートします './plugin.js' が必要です。 4. axupimgs/plugin.js を開き、次のコード行を設定します (設定する理由: これらのコード行の目的は、複数画像アップロードポップアップボックスの upfiles.html ファイルを導入することであるため)。 複数画像アップロード機能でダイアログボックスがポップアップ表示されたが、ダイアログボックスに内容が表示されない場合は、パスが正しくインポートされていない可能性があるため、再度設定する必要があります。 設定前: tinymce.PluginManager.add('axupimgs', 関数(エディター、URL) { var pluginName='複数の画像のアップロード'; window.axupimgs={}; // 外部のパブリック変数またはカスタムの場所をスローします var baseURL=tinymce.baseURL; var iframe1 = baseURL+'/plugins/axupimgs/upfiles.html'; 設定後: + '@/api/api.js' から api をインポートします tinymce.PluginManager.add('axupimgs', 関数(エディター、URL) { var pluginName='複数の画像のアップロード'; window.axupimgs={}; // 外部のパブリック変数またはカスタムの場所をスローします + var baseURL=api.editorUrl; + var iframe1 = baseURL+'tinymce/axupimgs/upfiles.html'; 注意:各人のプロジェクトは異なるため、パスの構成も異なります。自分のプロジェクトに合わせて構成することができます。 5. components/TEditor.vueにマルチイメージアップロードプラグインを導入し、プラグインとツールバーにプラグインを登録します(図を参照)。 import '../../public/tinymce/axupimgs' // 複数画像のアップロード 6. プロジェクトを更新または再起動します。注: この複数画像のアップロード機能は、単一画像のアップロード機能に基づいています。複数画像のアップロードは、単一画像のアップロード インターフェイス機能を複数回呼び出します (上部の images_upload_handler を参照)。 そのため、まずは単一画像アップロード機能を完成させる必要があります。単一画像アップロードはトップコードに実装されているので、ここでは詳細には触れません。 ファイルアップロード機能とメディアアップロード機能を追加します (アップロード機能には、画像アップロード、ファイルアップロード、メディアアップロードが含まれます。画像アップロードでは画像アップロード機能が使用され、ファイルとメディアのアップロードではどちらもファイルアップロード機能が使用されます) 参考資料: http://tinymce.ax-z.cn/general/upload-images.php 1. プラグインとツールバーにリンクプラグインとメディアプラグインを登録します(図を参照) 2. initに次のコードを追加します(次のコードはリンクプラグインとメディアプラグインに共通です。設定後は両方のプラグインが使用可能になります)(図を参照) file_picker_types: 'ファイル イメージ メディア', // リンク プラグイン、イメージおよび axupimgs プラグイン、メディア プラグインの 3 種類のファイルアップロードに対応します。特定のプラグインのアップロードをブロックしたい場合は、対応するパラメータfile_picker_callbackを削除します: (callback, value, meta)=>{ let filetype='.pdf、.txt、.zip、.rar、.7z、.doc、.docx、.xls、.xlsx、.ppt、.pptx、.mp3、.mp4、.jpg'; // ファイルのアップロード タイプを制限します。let inputElem = document.createElement('input'); // ファイル選択を作成します。inputElem.setAttribute('type'、'file'); inputElem.setAttribute('accept', ファイルタイプ); 入力要素をクリックします。 inputElem.onchange=()=>{ upurl='' とします let file=inputElem.files[0] //ファイル情報を取得 if(file.type.slice(0,5)=='video'){ //ファイルタイプを判定 upurl=`${api.baseUrl}/api-upload/uploadTxVideo` }それ以外{ upurl=`${api.baseUrl}/api-upload/upload` } if(file.type.slice(0,5)=='画像'&&file.size/1024/1024>2){ アラート("アップロードに失敗しました。画像サイズは 2M 以内にしてください") }それ以外の場合(file.type.slice(0,5)=='video'&&file.size/1024/1024>500){ アラート("アップロードに失敗しました。ビデオのサイズは 500 MB 以内にしてください") }そうでない場合(file.size/1024/1024>10){ アラート("アップロードに失敗しました。ファイルサイズを10MB以内にしてください") }それ以外{ パラメータ = new FormData() とする params.append('ファイル',ファイル) config={を設定します ヘッダー:{ "コンテンツタイプ":"マルチパート/フォームデータ" } } this.$axios.post(upurl,params,config).then(res=>{ res.data.code==200の場合{ callback(res.data.data) //アップロードに成功しました。コールバック関数にファイルパスを入力してください}else{ アラート("アップロードに失敗しました") } }).catch(()=>{ アラート("アップロード中にエラーが発生しました。サーバーがダウンしています") }) } } } 3. 具体的な効果については画像をご覧ください 統合された数式編集機能プロジェクトに数式編集機能が必要な場合 1. MathJax プラグイン + LaTeX 構文 数式編集機能といえば、まず思い浮かぶのは MathJax プラグインを導入して LaTeX 構文を使うことです。これにはいくつかの欠点があります。 1 つは、ユーザーが LaTeX 構文を知らないこと、もう 1 つは、vue の v-html では、LateX 構文でレンダリングされたリッチ テキストが効果的ではないことです。 LaTeX 構文のスラッシュ \ は v-html ではエスケープされるため、認識できなくなります。そこで、検討した結果、この実装を断念することにしました。 もちろん、プロジェクトで MathJax を問題なく使用している場合は、その方法を使用できます。実装方法についてはここでは説明しません。実装手順については、次のドキュメントを参照してください: https://www.cnblogs.com/already/p/12876452.html MathJax 使用ドキュメント 1: https://www.cnblogs.com/mqingqing123/p/12711372.html MathJax 使用ドキュメント 2: https://www.cnblogs.com/mqingqing123/p/12026817.html LaTeX 構文: https://www.jianshu.com/p/27b163b1c6ef 2. Baidu Editorのkityformulaを使用する 私は以前から Baidu Editor を使用しており、数式編集プラグイン kityformula がとても気に入っています。 ただし、KityFormula は Baidu Editor に依存しており、TinyMCE に個別に統合することはできません (個別に統合する方法があれば教えてください) したがって、プロジェクトに Baidu Editor を導入し、その数式編集機能のみを使用してから、Baidu Editor 全体を TinyMCE に統合することを検討してください。 実装手順1. このアドレスにアクセスして、ueditor パッケージをダウンロードします: https://files.cnblogs.com/files/huihuihero/UEditor.zip 2. 解凍したパッケージをtinymceフォルダと同じ階層のpublicフォルダにコピーします。 3. 数式編集用のプラグインを作成する 参考資料: http://tinymce.ax-z.cn/advanced/creating-a-plugin.php 1. public/tinymce フォルダに formulas という名前の新しいフォルダを作成します。2. formulas フォルダに新しい index.js ファイルを作成し、次のコードを記述します。// モジュール ローダーで使用するために「formulas」プラグインをエクスポートします。 // 使用法: // 共通JS: // require('tinymce/plugins/formulas') // ES2015: // 'tinymce/plugins/formulas' をインポートします './plugin.js' が必要です。 3. フォーミュラフォルダにplugin.jsとplugin.min.jsを作成し、次のコードを記述します。2つのファイルのコードは同じです。 import api from '@/api/api.js' tinymce.PluginManager.add('formulas', 関数(エディター, url) { var pluginName='数式'; //設定ファイルのインポートパスは、自分のプロジェクトに応じて、ここではapi.editorUrl=http://192.168.1.171/apibを紹介します //iframe1 で表されるページ アドレスは、オフラインで実行しているときにアクセス可能である必要があることに注意してください。そうでない場合は、デフォルトでプロジェクトのホームページに表示されます。var iframe1 = api.editorUrl+'tinymce/formulas/formulas.html'; var openDialog = 関数() { editor.windowManager.openUrl({ を返します。 タイトル: プラグイン名、 サイズ: 「大」、 url:iframe1, ボタン: [ { タイプ: 'キャンセル'、 テキスト: '閉じる' }, // { // タイプ: 'カスタム', // テキスト: '保存', // 名前: 'save', // プライマリ: true // }, ]、 }); }; // ツールバーボタン名を登録する editor.ui.registry.addButton('formulas', { テキスト: プラグイン名、 onAction: 関数 () { ダイアログを開きます。 } }); // メニュー項目名を登録する menu/menubar editor.ui.registry.addMenuItem('数式', { テキスト: プラグイン名、 onAction: 関数() { ダイアログを開きます。 } }); 戻る { getMetadata: 関数 () { 戻る { //プラグイン名とリンクは、「ヘルプ」→「プラグイン」→「インストール済みプラグイン」に表示されます。name: "Example plugin", //プラグイン名 url: "http://exampleplugindocsurl.com", //作成者 URL}; } }; }); 4. 数式フォルダにformulas.htmlという新しいフォームを作成し、次のコードを記述します。<!doctype html> <html> <ヘッド> <メタ文字セット="utf-8" /> <title>数式</title> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="format-detection" content="telephone=no"> <meta http-equiv="X-UA-compatible" content="IE=edge,chrome=1" /> <スタイル> html、本文{マージン:0;パディング:0;背景:#fff;} #包む{ 幅: 80%; 左マージン: 10%; } #エディタ{ 幅: 100%; 高さ: 300px; 上マージン: 40px; } .remind-a{ フォントサイズ: 14px; 色: #6f6f6f; 上マージン: 60px; } .remind-a span{ フォントサイズ: 16px; フォントの太さ: 700; 色: #333; } .remind-b{ フォントサイズ: 14px; 色: #6f6f6f; 上マージン: 10px; } </スタイル> </head> <本文> <div id="wrap"> <div id="エディター"></div> <div class="remind-a">数式を編集するには、左上隅の <span>∑</span> 記号をクリックします</div> <div class="remind-b">編集後、Ctrl+C を押してコピーし、Ctrl+V を押してエディターに貼り付けます</div> </div> </本文> <script type="text/javascript" src="../../UEditor/ueditor.config.js"></script> <script type="text/javascript" src="../../UEditor/ueditor.all.js"></script> <script type="text/javascript" src="../../UEditor/lang/zh-cn/zh-cn.js"></script> <script type="text/javascript" charset="utf-8" src="../../UEditor/kityformula-plugin/addKityFormulaDialog.js"></script> <script type="text/javascript" charset="utf-8" src="../../UEditor/kityformula-plugin/getKfContent.js"></script> <script type="text/javascript" charset="utf-8" src="../../UEditor/kityformula-plugin/defaultFilterFix.js"></script> <script id="editor" type="text/plain" name="gdesc" style="width:100%;height:350px;"></script> <script type="text/javascript"> //エディターをインスタンス化します var ue = UE.getEditor('editor', {toolbars: ["kityformula"]}); </スクリプト> </html> 4.自作数式編集プラグイン数式の紹介 src/components/TEditor.vue に数式編集プラグインをインポートし、プラグインとツールバーに登録します。import '../../public/tinymce/formulas' //数式編集 5. プロジェクトを再開し、数式編集機能の開発を完了する 最近、新しいプロジェクトを作成しました。@tinymce/tinymce-vue のバージョンが 4.0.0+ の場合、次のエラーが表示されます。したがって、エラーに遭遇した学生には、次のように4.0.0より前のバージョン番号を使用することをお勧めします(エラーを正常に解決します) 以上が、vue3.0+でtinymceを使用して、複数画像アップロード、ファイルアップロード、数式編集などの機能を実現する詳細です。vueの複数画像アップロード、ファイルアップロード数式編集の実装の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: mysql インストーラ ウェブ コミュニティ 5.7.21.0.msi インストール グラフィック チュートリアル
>>: Docker イメージを Docker Hub にプッシュする実装
最近、お客様から支援の依頼を受けました。管理されている通信コンピュータ ルームから、サーバーの 1 ...
質問最近、SSH フレームワークを使用して実用的なプロジェクトを完了していたときに、長い間悩まされて...
マイクリMyCLI は、自動補完と構文の強調表示を備えた MySQL、MariaDB、および Per...
操作中に Docker コンテナの公開ポートを変更または追加する必要がある場合がありますが、実行中の...
では、早速リソースについて見ていきましょう。 123WORDPRESS.COM ダウンロードSQLy...
utf8mb4 エンコーディングは utf8 エンコーディングのスーパーセットであり、utf8 と互...
これは、Web ページを Windows のスタート メニューなどのデスクトップ プログラムのように...
div を使用してマスクを作成したり、ポップアップ ウィンドウをシミュレートしたりします。ただし、I...
デフォルトでは、セルの幅と高さはコンテンツに応じて自動的に調整されますが、セルの幅と高さを手動で設定...
1. CSSは左の固定幅と右の適応幅を実現します1. ポジショニング <!DOCTYPE ht...
私のシステムとソフトウェアのバージョンは次のとおりです。システム環境: win7、64ビットMySQ...
何もすることがなかったので、学習用に最も安いAlibaba Cloudサーバーを購入しました。年間3...
この記事では、ショッピングカートを実装するためのJavaScriptの具体的なコードを参考までに紹介...
この記事ではUbuntuでC++インターフェースを使用してopencvをインストールする方法について...
目次序文1. 404 ページ1. 原因2. 解決策2.白い画面を更新する1. 原因2. 解決策3. ...