annotate .cms/lib/codemirror/mode/asterisk/asterisk.js @ 0:78edf6b517a0 draft

24.10
author Coffee CMS <info@coffee-cms.ru>
date Fri, 11 Oct 2024 22:40:23 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
3
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
4 /*
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
5 * =====================================================================================
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
6 *
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
7 * Filename: mode/asterisk/asterisk.js
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
8 *
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
9 * Description: CodeMirror mode for Asterisk dialplan
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
10 *
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
11 * Created: 05/17/2012 09:20:25 PM
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
12 * Revision: 08/05/2019 AstLinux Project: Support block-comments
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
13 *
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
14 * Author: Stas Kobzar (stas@modulis.ca),
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
15 * Company: Modulis.ca Inc.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
16 *
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
17 * =====================================================================================
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
18 */
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
19
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
20 (function(mod) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
21 if (typeof exports == "object" && typeof module == "object") // CommonJS
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
22 mod(require("../../lib/codemirror"));
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
23 else if (typeof define == "function" && define.amd) // AMD
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
24 define(["../../lib/codemirror"], mod);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
25 else // Plain browser env
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
26 mod(CodeMirror);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
27 })(function(CodeMirror) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
28 "use strict";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
29
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
30 CodeMirror.defineMode("asterisk", function() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
31 var atoms = ["exten", "same", "include","ignorepat","switch"],
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
32 dpcmd = ["#include","#exec"],
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
33 apps = [
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
34 "addqueuemember","adsiprog","aelsub","agentlogin","agentmonitoroutgoing","agi",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
35 "alarmreceiver","amd","answer","authenticate","background","backgrounddetect",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
36 "bridge","busy","callcompletioncancel","callcompletionrequest","celgenuserevent",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
37 "changemonitor","chanisavail","channelredirect","chanspy","clearhash","confbridge",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
38 "congestion","continuewhile","controlplayback","dahdiacceptr2call","dahdibarge",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
39 "dahdiras","dahdiscan","dahdisendcallreroutingfacility","dahdisendkeypadfacility",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
40 "datetime","dbdel","dbdeltree","deadagi","dial","dictate","directory","disa",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
41 "dumpchan","eagi","echo","endwhile","exec","execif","execiftime","exitwhile","extenspy",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
42 "externalivr","festival","flash","followme","forkcdr","getcpeid","gosub","gosubif",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
43 "goto","gotoif","gotoiftime","hangup","iax2provision","ices","importvar","incomplete",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
44 "ivrdemo","jabberjoin","jabberleave","jabbersend","jabbersendgroup","jabberstatus",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
45 "jack","log","macro","macroexclusive","macroexit","macroif","mailboxexists","meetme",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
46 "meetmeadmin","meetmechanneladmin","meetmecount","milliwatt","minivmaccmess","minivmdelete",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
47 "minivmgreet","minivmmwi","minivmnotify","minivmrecord","mixmonitor","monitor","morsecode",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
48 "mp3player","mset","musiconhold","nbscat","nocdr","noop","odbc","odbc","odbcfinish",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
49 "originate","ospauth","ospfinish","osplookup","ospnext","page","park","parkandannounce",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
50 "parkedcall","pausemonitor","pausequeuemember","pickup","pickupchan","playback","playtones",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
51 "privacymanager","proceeding","progress","queue","queuelog","raiseexception","read","readexten",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
52 "readfile","receivefax","receivefax","receivefax","record","removequeuemember",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
53 "resetcdr","retrydial","return","ringing","sayalpha","saycountedadj","saycountednoun",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
54 "saycountpl","saydigits","saynumber","sayphonetic","sayunixtime","senddtmf","sendfax",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
55 "sendfax","sendfax","sendimage","sendtext","sendurl","set","setamaflags",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
56 "setcallerpres","setmusiconhold","sipaddheader","sipdtmfmode","sipremoveheader","skel",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
57 "slastation","slatrunk","sms","softhangup","speechactivategrammar","speechbackground",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
58 "speechcreate","speechdeactivategrammar","speechdestroy","speechloadgrammar","speechprocessingsound",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
59 "speechstart","speechunloadgrammar","stackpop","startmusiconhold","stopmixmonitor","stopmonitor",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
60 "stopmusiconhold","stopplaytones","system","testclient","testserver","transfer","tryexec",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
61 "trysystem","unpausemonitor","unpausequeuemember","userevent","verbose","vmauthenticate",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
62 "vmsayname","voicemail","voicemailmain","wait","waitexten","waitfornoise","waitforring",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
63 "waitforsilence","waitmusiconhold","waituntil","while","zapateller"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
64 ];
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
65
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
66 function basicToken(stream,state){
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
67 var cur = '';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
68 var ch = stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
69 // comment
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
70 if (state.blockComment) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
71 if (ch == "-" && stream.match("-;", true)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
72 state.blockComment = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
73 } else if (stream.skipTo("--;")) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
74 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
75 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
76 stream.next();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
77 state.blockComment = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
78 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
79 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
80 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
81 return "comment";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
82 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
83 if(ch == ";") {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
84 if (stream.match("--", true)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
85 if (!stream.match("-", false)) { // Except ;--- is not a block comment
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
86 state.blockComment = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
87 return "comment";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
88 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
89 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
90 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
91 return "comment";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
92 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
93 // context
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
94 if(ch == '[') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
95 stream.skipTo(']');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
96 stream.eat(']');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
97 return "header";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
98 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
99 // string
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
100 if(ch == '"') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
101 stream.skipTo('"');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
102 return "string";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
103 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
104 if(ch == "'") {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
105 stream.skipTo("'");
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
106 return "string-2";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
107 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
108 // dialplan commands
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
109 if(ch == '#') {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
110 stream.eatWhile(/\w/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
111 cur = stream.current();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
112 if(dpcmd.indexOf(cur) !== -1) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
113 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
114 return "strong";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
115 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
116 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
117 // application args
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
118 if(ch == '$'){
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
119 var ch1 = stream.peek();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
120 if(ch1 == '{'){
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
121 stream.skipTo('}');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
122 stream.eat('}');
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
123 return "variable-3";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
124 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
125 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
126 // extension
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
127 stream.eatWhile(/\w/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
128 cur = stream.current();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
129 if(atoms.indexOf(cur) !== -1) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
130 state.extenStart = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
131 switch(cur) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
132 case 'same': state.extenSame = true; break;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
133 case 'include':
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
134 case 'switch':
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
135 case 'ignorepat':
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
136 state.extenInclude = true;break;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
137 default:break;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
138 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
139 return "atom";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
140 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
141 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
142
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
143 return {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
144 startState: function() {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
145 return {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
146 blockComment: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
147 extenStart: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
148 extenSame: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
149 extenInclude: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
150 extenExten: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
151 extenPriority: false,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
152 extenApplication: false
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
153 };
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
154 },
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
155 token: function(stream, state) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
156
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
157 var cur = '';
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
158 if(stream.eatSpace()) return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
159 // extension started
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
160 if(state.extenStart){
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
161 stream.eatWhile(/[^\s]/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
162 cur = stream.current();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
163 if(/^=>?$/.test(cur)){
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
164 state.extenExten = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
165 state.extenStart = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
166 return "strong";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
167 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
168 state.extenStart = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
169 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
170 return "error";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
171 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
172 } else if(state.extenExten) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
173 // set exten and priority
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
174 state.extenExten = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
175 state.extenPriority = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
176 stream.eatWhile(/[^,]/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
177 if(state.extenInclude) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
178 stream.skipToEnd();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
179 state.extenPriority = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
180 state.extenInclude = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
181 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
182 if(state.extenSame) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
183 state.extenPriority = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
184 state.extenSame = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
185 state.extenApplication = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
186 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
187 return "tag";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
188 } else if(state.extenPriority) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
189 state.extenPriority = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
190 state.extenApplication = true;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
191 stream.next(); // get comma
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
192 if(state.extenSame) return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
193 stream.eatWhile(/[^,]/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
194 return "number";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
195 } else if(state.extenApplication) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
196 stream.eatWhile(/,/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
197 cur = stream.current();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
198 if(cur === ',') return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
199 stream.eatWhile(/\w/);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
200 cur = stream.current().toLowerCase();
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
201 state.extenApplication = false;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
202 if(apps.indexOf(cur) !== -1){
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
203 return "def strong";
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
204 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
205 } else{
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
206 return basicToken(stream,state);
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
207 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
208
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
209 return null;
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
210 },
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
211
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
212 blockCommentStart: ";--",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
213 blockCommentEnd: "--;",
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
214 lineComment: ";"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
215 };
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
216 });
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
217
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
218 CodeMirror.defineMIME("text/x-asterisk", "asterisk");
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
219
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
220 });